1 // Written by Christopher E. Miller 2 // See the included license.txt for copyright and license details. 3 4 5 /// 6 module dfl.colordialog; 7 8 private import dfl.commondialog, dfl.base, dfl.internal.winapi, dfl.internal.wincom; 9 private import dfl.internal.utf, dfl.application, dfl.drawing, dfl.internal.dlib; 10 11 12 /// 13 class ColorDialog: CommonDialog // docmain 14 { 15 this() 16 { 17 Application.ppin(cast(void*)this); 18 19 cc.lStructSize = cc.sizeof; 20 cc.Flags = INIT_FLAGS; 21 cc.rgbResult = Color.empty.toArgb(); 22 cc.lCustData = cast(typeof(cc.lCustData))cast(void*)this; 23 cc.lpfnHook = cast(typeof(cc.lpfnHook))&ccHookProc; 24 _initcust(); 25 } 26 27 28 /// 29 @property void allowFullOpen(bool byes) // setter 30 { 31 if(byes) 32 cc.Flags &= ~CC_PREVENTFULLOPEN; 33 else 34 cc.Flags |= CC_PREVENTFULLOPEN; 35 } 36 37 /// ditto 38 @property bool allowFullOpen() // getter 39 { 40 return (cc.Flags & CC_PREVENTFULLOPEN) != CC_PREVENTFULLOPEN; 41 } 42 43 44 /// 45 @property void anyColor(bool byes) // setter 46 { 47 if(byes) 48 cc.Flags |= CC_ANYCOLOR; 49 else 50 cc.Flags &= ~CC_ANYCOLOR; 51 } 52 53 /// ditto 54 @property bool anyColor() // getter 55 { 56 return (cc.Flags & CC_ANYCOLOR) == CC_ANYCOLOR; 57 } 58 59 60 /// 61 @property void solidColorOnly(bool byes) // setter 62 { 63 if(byes) 64 cc.Flags |= CC_SOLIDCOLOR; 65 else 66 cc.Flags &= ~CC_SOLIDCOLOR; 67 } 68 69 /// ditto 70 @property bool solidColorOnly() // getter 71 { 72 return (cc.Flags & CC_SOLIDCOLOR) == CC_SOLIDCOLOR; 73 } 74 75 76 /// 77 final @property void color(Color c) // setter 78 { 79 cc.rgbResult = c.toRgb(); 80 } 81 82 /// ditto 83 final @property Color color() // getter 84 { 85 return Color.fromRgb(cc.rgbResult); 86 } 87 88 89 /// 90 final @property void customColors(COLORREF[] colors) // setter 91 { 92 if(colors.length >= _cust.length) 93 _cust[] = colors[0 .. _cust.length]; 94 else 95 _cust[0 .. colors.length] = colors[]; 96 } 97 98 /// ditto 99 final @property COLORREF[] customColors() // getter 100 { 101 return _cust; 102 } 103 104 105 /// 106 @property void fullOpen(bool byes) // setter 107 { 108 if(byes) 109 cc.Flags |= CC_FULLOPEN; 110 else 111 cc.Flags &= ~CC_FULLOPEN; 112 } 113 114 /// ditto 115 @property bool fullOpen() // getter 116 { 117 return (cc.Flags & CC_FULLOPEN) == CC_FULLOPEN; 118 } 119 120 121 /// 122 @property void showHelp(bool byes) // setter 123 { 124 if(byes) 125 cc.Flags |= CC_SHOWHELP; 126 else 127 cc.Flags &= ~CC_SHOWHELP; 128 } 129 130 /// ditto 131 @property bool showHelp() // getter 132 { 133 return (cc.Flags & CC_SHOWHELP) == CC_SHOWHELP; 134 } 135 136 137 /// 138 override DialogResult showDialog() 139 { 140 return runDialog(GetActiveWindow()) ? 141 DialogResult.OK : DialogResult.CANCEL; 142 } 143 144 /// ditto 145 override DialogResult showDialog(IWindow owner) 146 { 147 return runDialog(owner ? owner.handle : GetActiveWindow()) ? 148 DialogResult.OK : DialogResult.CANCEL; 149 } 150 151 152 /// 153 override void reset() 154 { 155 cc.Flags = INIT_FLAGS; 156 cc.rgbResult = Color.empty.toArgb(); 157 _initcust(); 158 } 159 160 161 /// 162 protected override bool runDialog(HWND owner) 163 { 164 if(!_runDialog(owner)) 165 { 166 if(!CommDlgExtendedError()) 167 return false; 168 _cantrun(); 169 } 170 return true; 171 } 172 173 174 private BOOL _runDialog(HWND owner) 175 { 176 if(cc.rgbResult == Color.empty.toArgb()) 177 cc.Flags &= ~CC_RGBINIT; 178 else 179 cc.Flags |= CC_RGBINIT; 180 cc.hwndOwner = owner; 181 cc.lpCustColors = _cust.ptr; 182 return ChooseColorA(&cc); 183 } 184 185 186 private: 187 enum DWORD INIT_FLAGS = CC_ENABLEHOOK; 188 189 CHOOSECOLORA cc; 190 COLORREF[16] _cust; 191 192 193 void _initcust() 194 { 195 COLORREF cdef; 196 cdef = Color(0xFF, 0xFF, 0xFF).toRgb(); 197 foreach(ref COLORREF cref; _cust) 198 { 199 cref = cdef; 200 } 201 } 202 } 203 204 205 private extern(Windows) UINT ccHookProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 206 { 207 enum PROP_STR = "DFL_ColorDialog"; 208 ColorDialog cd; 209 UINT result = 0; 210 211 try 212 { 213 if(msg == WM_INITDIALOG) 214 { 215 CHOOSECOLORA* cc; 216 cc = cast(CHOOSECOLORA*)lparam; 217 SetPropA(hwnd, PROP_STR.ptr, cast(HANDLE)cc.lCustData); 218 cd = cast(ColorDialog)cast(void*)cc.lCustData; 219 } 220 else 221 { 222 cd = cast(ColorDialog)cast(void*)GetPropA(hwnd, PROP_STR.ptr); 223 } 224 225 if(cd) 226 { 227 result = cast(UINT)cd.hookProc(hwnd, msg, wparam, lparam); 228 } 229 } 230 catch(DThrowable e) 231 { 232 Application.onThreadException(e); 233 } 234 235 return result; 236 } 237