Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/src/icon.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 112 - (show annotations) (download) (as text)
Mon Sep 10 13:12:57 2012 UTC (11 years, 7 months ago) by z0rac
File MIME type: text/x-c++src
File size: 3933 byte(s)
Change mail address.
1 /*
2 * Copyright (C) 2009-2011 TSUBAKIMOTO Hiroya <z0rac@users.sourceforge.jp>
3 *
4 * This software comes with ABSOLUTELY NO WARRANTY; for details of
5 * the license terms, see the LICENSE.txt file included with the program.
6 */
7 #include "icon.h"
8 #include <cassert>
9 #include <stdexcept>
10 #include <shlwapi.h>
11
12 #ifdef _DEBUG
13 #include <iostream>
14 #define DBG(s) s
15 #define LOG(s) (cout << s)
16 #else
17 #define DBG(s)
18 #define LOG(s)
19 #endif
20
21 #define RT_MASCOTICON "MASCOTICON"
22
23 /*
24 * Functions of the class iconmodule
25 */
26 iconmodule::iconmodule(const string& fn)
27 : _rep(new rep(fn.empty() ? HMODULE(win32::exe) :
28 LoadLibraryEx(path(fn.c_str()).c_str(), NULL, LOAD_LIBRARY_AS_DATAFILE)))
29 {}
30
31 iconmodule::iconmodule(const iconmodule& module)
32 : _rep(module._rep)
33 {
34 ++_rep->count;
35 }
36
37 iconmodule&
38 iconmodule::operator=(const iconmodule& module)
39 {
40 ++module._rep->count;
41 _release();
42 _rep = module._rep;
43 return *this;
44 }
45
46 void
47 iconmodule::_release()
48 {
49 if (--_rep->count == 0) delete _rep;
50 }
51
52 string
53 iconmodule::path(LPCSTR fn)
54 {
55 char path[MAX_PATH];
56 win32::valid(GetModuleFileName(NULL, path, MAX_PATH));
57 fn && *fn && win32::valid(PathRemoveFileSpec(path) && PathCombine(path, path, fn));
58 return path;
59 }
60
61 void
62 iconmodule::collect(accept& accept) const
63 {
64 if (!_rep->module) return;
65
66 struct _iconenum {
67 const iconmodule* module;
68 iconmodule::accept* accept;
69
70 static BOOL CALLBACK proc(HMODULE, LPCSTR, LPSTR name, LONG_PTR param)
71 {
72 try {
73 int id = LOWORD(name);
74 if (name != MAKEINTRESOURCE(id)) {
75 if (name[0] != '#') return TRUE;
76 id = StrToInt(name + 1);
77 }
78 _iconenum* p = reinterpret_cast<_iconenum*>(param);
79 (*p->accept)(id, icon(id, *p->module));
80 } catch (...) {}
81 return TRUE;
82 }
83 } param = { this, &accept };
84 EnumResourceNames(_rep->module, RT_MASCOTICON, _iconenum::proc, LONG_PTR(&param));
85 }
86
87 /*
88 * Functions of the class icon
89 */
90 icon::icon(int id, const iconmodule& mod)
91 : _mod(win32::valid(mod)), _anim(NULL), _step(0), _icon(NULL)
92 {
93 HRSRC h = win32::valid(FindResource(_mod, MAKEINTRESOURCE(id), RT_MASCOTICON));
94 DWORD rsz = SizeofResource(_mod, h);
95 _rc = PWORD(win32::valid(LockResource(LoadResource(_mod, h))));
96 if (rsz < 2 || (_rc[0] & 1) || rsz < _rc[0] || _rc[0] < 8 ||
97 _rc[2] == 0 || rsz < _rc[0] + _rc[2] * sizeof(anim)) {
98 throw runtime_error("Invalid icon resource.");
99 }
100 for (int t = 0; t < 3; ++t) {
101 const anim* p = reinterpret_cast<anim*>(PBYTE(_rc) + _rc[0]) + _rc[2] * t;
102 for (int i = 0; i < _rc[2]; ++i) {
103 win32::valid(FindResource(_mod, MAKEINTRESOURCE(p[i].id), RT_GROUP_ICON));
104 if (p[i].ticks == 0) break;
105 }
106 }
107 _size = size();
108 }
109
110 icon::~icon()
111 {
112 _icon && DestroyIcon(_icon);
113 }
114
115 icon&
116 icon::operator=(const icon& copy)
117 {
118 if (this != &copy) {
119 _mod = copy._mod, _rc = copy._rc, _anim = NULL, _size = copy._size, _step = 0;
120 if (_icon) DestroyIcon(_icon), _icon = NULL;
121 }
122 return *this;
123 }
124
125 HICON
126 icon::_read(int id, int size) const
127 {
128 if (size <= 0) size = _size;
129 return HICON(LoadImage(_mod, MAKEINTRESOURCE(id),
130 IMAGE_ICON, size, size, LR_DEFAULTCOLOR));
131 }
132
133 icon&
134 icon::_load(int step)
135 {
136 assert(step >= 0 && step < _rc[2]);
137 HICON icon = _read(_anim ? _anim[_step = _anim[step].id ? step : 0].id : _rc[3]);
138 if (icon) {
139 if (_icon) DestroyIcon(_icon);
140 _icon = icon;
141 }
142 return *this;
143 }
144
145 icon&
146 icon::resize(int size)
147 {
148 assert(size > 0);
149 if (_size != size) _size = size, _load();
150 return *this;
151 }
152
153 icon&
154 icon::reset(int type)
155 {
156 assert(type >= 0 && type <= 2);
157 _anim = reinterpret_cast<anim*>(PBYTE(_rc) + _rc[0]) + _rc[2] * type;
158 return _load();
159 }
160
161 icon&
162 icon::next()
163 {
164 return _load((_step + 1) % _rc[2]);
165 }
166
167 UINT
168 icon::delay() const
169 {
170 return _anim ? _anim[_step].ticks * 50 / 3 : 0;
171 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26