xref: /reactos/base/applications/calc/convert.c (revision c2d0d784)
1 #include "calc.h"
2 
3 /*
4     The conversion is made by converting the "from" unit
5     into the I.S. unit and then the I.S. unit is converted
6     into the "from" one.
7 
8     The base units for all categories are:
9 
10     ANGLE..........degrees
11     AREA...........square meters
12     CONSUMPTION....kilometers per liter
13     CURRENCY.......Euro
14     ENERGY.........joule
15     LENGTHS........meters
16     POWER..........Watt
17     PRESSURE.......Pascal
18     TEMPERATURE....kelvin
19     TIME...........seconds
20     VELOCITY.......meters per second
21     VOLUME.........liter
22     WEIGHT.........gram
23 
24     The '$' character is used as "what you read into the display".
25 */
26 typedef struct {
27     DWORD unit;
28     const char *formula_from;
29     const char *formula_to;
30 } conv_t;
31 
32 typedef struct {
33     const DWORD   category;
34     const conv_t *items;
35 } conv_category_t;
36 
37 #define DECLARE_CONV_CAT(_category) \
38     { IDS_CONV_##_category, conv_##_category },
39 
40 #define DECLARE_CONV_UNIT(_category, _unit, _from, _to ) \
41     { IDS_##_category##_##_unit, _from, _to },
42 
43 #define DECLARE_CONV_END \
44     { 0, NULL, NULL },
45 
46 /*
47     1 gradian = 0.9 deg
48     1 radian = 57.29577951308233 deg
49 */
50 static const conv_t conv_ANGLE[] = {
51     DECLARE_CONV_UNIT(ANGLE, DEGREES,  "$", "$")
52     DECLARE_CONV_UNIT(ANGLE, GRADIANS, "$*0.9", "$/0.9")
53     DECLARE_CONV_UNIT(ANGLE, RADIANS,  "$/P*180", "$*P/180")
54     DECLARE_CONV_END
55 };
56 
57 /*
58     1 acre ................ = 4840 square yd = 4046,8564224 mq
59     1 acre brazil ......... =
60     1 acre france ......... =
61     1 acre scots .......... = 5000 mq
62     1 acre us ............. = 4840*(36/39.37)^2 m = 6272640/1549.9969 m
63     1 are ................. = 100 mq
64     1 chou ................ = 108000*(10/33)^2 mq
65     1 danbo ............... =
66     1 ha .................. = 10000 mq
67     1 jeongbo ............. =
68     1 morgen hungary ...... =
69     1 mu .................. = 2000/3 mq
70     1 ping ................ =
71     1 pyeong .............. =
72     1 pyeongbangja ........ =
73     1 rai ................. = 1600 mq
74     1 se .................. = 1080*(10/33)^2 mq
75     1 square cm ........... = 0.0001 mq
76     1 square chr .......... =
77     1 square fathom ....... = 1.8288^2 = 3.34450944 mq
78     1 square fathom hungary = 1.8964838^2 = 3.59665080366244 mq
79     1 square ft ........... = 0,09290304 mq
80     1 square in ........... = 0,00064516 mq
81     1 square km ........... = 1000000 mq
82     1 square lar .......... =
83     1 square mile ......... = 1609.344^2 = 2589988.110336 mq
84     1 square mm ........... = 0,000001 mq
85     1 square shaku ........ = (10/33)^2 mq
86     1 square tsuen ........ =
87     1 square va ........... =
88     1 square yard ......... = 0,83612736 mq
89     1 tan ................. = 10800*(10/33)^2 mq
90     1 tsubo ............... = 36*(10/33)^2 mq
91 */
92 static const conv_t conv_AREA[] = {
93     DECLARE_CONV_UNIT(AREA, ACRES,                  "$*4046,8564224",    "$/4046,8564224")
94 //    DECLARE_CONV_UNIT(AREA, ACRES_BRAZIL,           "$", "$")
95 //    DECLARE_CONV_UNIT(AREA, ACRES_FRANCE,           "$", "$")
96     DECLARE_CONV_UNIT(AREA, ACRES_US,               "$*627264/154.99969", "$/627264*154.99969")
97     DECLARE_CONV_UNIT(AREA, ACRES_SCOTS,            "$*5000",            "$/5000")
98     DECLARE_CONV_UNIT(AREA, ARES,                   "$*100",             "$/100")
99     DECLARE_CONV_UNIT(AREA, CHOU,                   "$*10800000/1089",   "$*1089/10800000")
100 //    DECLARE_CONV_UNIT(AREA, DANBO,                  "$", "$")
101     DECLARE_CONV_UNIT(AREA, HECTARES,               "$*10000",           "$/10000")
102 //    DECLARE_CONV_UNIT(AREA, JEONGBO,                "$", "$")
103 //    DECLARE_CONV_UNIT(AREA, MORGEN_HUNGARY,         "$", "$")
104     DECLARE_CONV_UNIT(AREA, MU,                     "$*(2000/3)", "$/(2000/3)")
105 //    DECLARE_CONV_UNIT(AREA, PING,                   "$", "$")
106 //    DECLARE_CONV_UNIT(AREA, PYEONG,                 "$", "$")
107 //    DECLARE_CONV_UNIT(AREA, PYEONGBANGJA,           "$", "$")
108     DECLARE_CONV_UNIT(AREA, RAI,                    "$*1600", "$/1600")
109     DECLARE_CONV_UNIT(AREA, SE,                     "$*108000/1089",     "$*1089/108000")
110     DECLARE_CONV_UNIT(AREA, SQUARE_CENTIMETERS,     "$*0,0001",          "$/0,0001")
111 //    DECLARE_CONV_UNIT(AREA, SQUARE_CHR,             "$", "$")
112     DECLARE_CONV_UNIT(AREA, SQUARE_FATHOMS,         "$*3.34450944",      "$/3.34450944")
113     DECLARE_CONV_UNIT(AREA, SQUARE_FATHOMS_HUNGARY, "$*3.59665080366244", "$/3.59665080366244")
114     DECLARE_CONV_UNIT(AREA, SQUARE_FEET,            "$*0,09290304",      "$/0,09290304")
115     DECLARE_CONV_UNIT(AREA, SQUARE_INCHES,          "$*0,00064516",      "$/0.00064516")
116     DECLARE_CONV_UNIT(AREA, SQUARE_KILOMETERS,      "$*1000000",         "$/1000000")
117 //    DECLARE_CONV_UNIT(AREA, SQUARE_LAR,             "$", "$")
118     DECLARE_CONV_UNIT(AREA, SQUARE_METER,           "$",                 "$")
119     DECLARE_CONV_UNIT(AREA, SQUARE_MILES,           "$*2589988.110336",  "$/2589988.110336")
120     DECLARE_CONV_UNIT(AREA, SQUARE_MILLIMETERS,     "$*1000000",         "$/1000000")
121     DECLARE_CONV_UNIT(AREA, SQUARE_SHAKU,           "$*100/1089",        "$/1089*100")
122 //    DECLARE_CONV_UNIT(AREA, SQUARE_TSUEN,           "$", "$")
123 //    DECLARE_CONV_UNIT(AREA, SQUARE_VA,              "$", "$")
124     DECLARE_CONV_UNIT(AREA, SQUARE_YARD,            "$*0,83612736",      "$/0,83612736")
125     DECLARE_CONV_UNIT(AREA, TAN,                    "$*1080000/1089",    "$*1089/1080000")
126     DECLARE_CONV_UNIT(AREA, TSUBO,                  "$*1188/1089",       "$*1089/1188")
127     DECLARE_CONV_END
128 };
129 
130 /*
131     1 l/100Km = 100 km/l -> y = 100/x
132     1 miles/gal uk = 1.609344/4.54609 km/l
133     1 miles/gal us = 1.609344/3.785411784 km/l
134 */
135 static const conv_t conv_CONSUMPTION[] = {
136     DECLARE_CONV_UNIT(CONSUMPTION, KM_PER_L,        "$", "$")
137     DECLARE_CONV_UNIT(CONSUMPTION, L_PER_100_KM,    "100/$", "100/$")
138     DECLARE_CONV_UNIT(CONSUMPTION, MILES_GALLON_UK, "$*1.609344/4.54609", "$/1.609344*4.54609")
139     DECLARE_CONV_UNIT(CONSUMPTION, MILES_GALLON_US, "$*1.609344/3.785411784", "$/1.609344*3.785411784")
140     DECLARE_CONV_END
141 };
142 
143 static const conv_t conv_CURRENCY[] = {
144     DECLARE_CONV_UNIT(CURRENCY, AUSTRIAN_SCHILLING, "$/13,7603", "$*13,7603")
145     DECLARE_CONV_UNIT(CURRENCY, BELGIAN_FRANC,      "$/40,3399", "$*40,3399")
146     DECLARE_CONV_UNIT(CURRENCY, CYPRIOT_POUND,      "$/0,585274","$*0,585274")
147     DECLARE_CONV_UNIT(CURRENCY, CZECH_KORUNA,       "$/27,9766", "$*27,9766")
148     DECLARE_CONV_UNIT(CURRENCY, DEUTSCHE_MARK,      "$/1,9558",  "$*1,9558")
149     DECLARE_CONV_UNIT(CURRENCY, DUTCH_GUILDER,      "$/2,20371", "$*2,20371")
150     DECLARE_CONV_UNIT(CURRENCY, EURO,               "$",         "$")
151     DECLARE_CONV_UNIT(CURRENCY, FINNISH_MARKKA,     "$/5,9457",  "$*5,9457")
152     DECLARE_CONV_UNIT(CURRENCY, FRENCH_FRANC,       "$/6,5596",  "$*6,5596")
153     DECLARE_CONV_UNIT(CURRENCY, GREEK_DRACHMA,      "$/340,75",  "$*340,75")
154     DECLARE_CONV_UNIT(CURRENCY, IRISH_POUND,        "$/0,7876",  "$*0,7876")
155     DECLARE_CONV_UNIT(CURRENCY, ITALIAN_LIRA,       "$/1936.27", "$*1936.27")
156     DECLARE_CONV_UNIT(CURRENCY, LUXEMBOURG_FRANC,   "$/40,3399", "$*40,3399")
157     DECLARE_CONV_UNIT(CURRENCY, MALTESE_LIRA,       "$/0.42930", "$*0.42930")
158     DECLARE_CONV_UNIT(CURRENCY, PORTOGUESE_ESCUDO,  "$/200,482", "$*200,482")
159     DECLARE_CONV_UNIT(CURRENCY, SLOVAK_KORUNA,      "$/30,126",  "$*30,126")
160     DECLARE_CONV_UNIT(CURRENCY, SLOVENIAN_TOLAR,    "$/239,640", "$*239,640")
161     DECLARE_CONV_UNIT(CURRENCY, SPANISH_PESETA,     "$/166,386", "$*166,386")
162     DECLARE_CONV_END
163 };
164 
165 /*
166     1 cal15 .... = 4.1855 J
167     1 BTU ...... = 1055.056 J
168     1 ERG ...... = 0.0000001 J
169     1 EV ....... = 0.000000000000000000160217653 J
170     1 Foot-Pound = 1.3558179483314004 J
171     1 IT calorie = 4.1868 J
172     1 KCa ...... = 4186.8 J
173     1 KJ ....... = 1000 J
174     1 KWh ...... = 3600 J
175     1 IUNS ..... = 4.182 J
176     1 calth .... = 4.184 J
177 */
178 static const conv_t conv_ENERGY[] = {
179     DECLARE_CONV_UNIT(ENERGY, 15_C_CALORIES,        "$*4.1855",   "$/4.1855")
180     DECLARE_CONV_UNIT(ENERGY, BTUS,                 "$*1055.056", "$/1055.056")
181     DECLARE_CONV_UNIT(ENERGY, ERGS,                 "$*.0000001", "$/.0000001")
182     DECLARE_CONV_UNIT(ENERGY, EVS,                  "$*.000000000000000000160217653", "$/.000000000000000000160217653")
183     DECLARE_CONV_UNIT(ENERGY, FOOT_POUNDS,          "$*1.3558179483314004",   "$/1.3558179483314004")
184     DECLARE_CONV_UNIT(ENERGY, IT_CALORIES,          "$*4.1868",   "$/4.1868")
185     DECLARE_CONV_UNIT(ENERGY, IT_KILOCALORIES,      "$*4186.8",   "$/4186.8")
186     DECLARE_CONV_UNIT(ENERGY, JOULES,               "$",          "$")
187     DECLARE_CONV_UNIT(ENERGY, KILOJOULES,           "$*1000",     "$/1000")
188     DECLARE_CONV_UNIT(ENERGY, KILOWATT_HOURS,       "$*3600",     "$/3600")
189     DECLARE_CONV_UNIT(ENERGY, NUTRITION_CALORIES,   "$*4.182",    "$/4.182")
190     DECLARE_CONV_UNIT(ENERGY, TH_CALORIES,          "$*4.184",    "$/4.184")
191     DECLARE_CONV_END
192 };
193 
194 /*
195     1 angstrom ....... = 0.0000000001 m
196     1 astronomical unit= 149598000000 m
197     1 barleycorn ..... = 1/3 inch = 0.9144/108 m
198     1 cm ............. = 1/100 m
199     1 chain uk ....... = 22 yards = 22*0.9144 m
200     1 chi ............ = 1/3 m
201     1 chou ........... = 3600/33 m
202     1 chr ............ =
203     1 cun ............ = 1/10 chi = 1/30 m
204     1 fathom ......... = 2 yard = 2*0.9144 m
205     1 fathom ungary .. = 1.8964838 m (fixed)
206     1 feet ........... = 12 inch = 0.9144/3 m
207     1 furlong ........ = 10 chains = 220*0.9144 m
208     1 gan ............ =
209     1 hand ........... = 4 inches = 0.9144/9 m
210     1 hunh ........... =
211     1 inch ........... = yard/36 = 0.9144/36 m
212     1 ja ............. =
213     1 jeong .......... =
214     1 kabiet ......... =
215     1 ken ............ = 60/33 m
216     1 keub ........... =
217     1 km ............. = 1000 m
218     1 lar ............ =
219     1 light year ..... = 9460730472580800 m
220     1 link uk ........ = 0.01 chains = 0.22*0.9144 m
221     1 micron ......... = 0.000001 m
222     1 mile ........... = 1760 yards = 1609.344 m
223     1 millimeter ..... = 1/1000 m
224     1 nautical mile .. = 1852 m
225     1 nieu ........... =
226     1 parsec ......... = 30856800000000000 m
227     1 pica ........... = yard/216 = 0.9144/216 m
228     1 ri japan ....... =
229     1 ri korea ....... =
230     1 rod ............ = 5.0292 m
231     1 sawk ........... =
232     1 sen ............ =
233     1 shaku .......... = 10/33 m
234     1 span ........... = 9 inches = 0.9144/4 m
235     1 sun ............ = 1/33 m
236     1 tsuen .......... =
237     1 va ............. =
238     1 yard ........... = 0.9144 m
239     1 yote ........... =
240     1 zhang .......... =
241 */
242 static const conv_t conv_LENGTH[] = {
243     DECLARE_CONV_UNIT(LENGTH, ANGSTROMS,            "$*0.0000000001",   "$/0.0000000001")
244     DECLARE_CONV_UNIT(LENGTH, ASTRONOMICAL_UNITS,   "$*149598000000",   "$/149598000000")
245     DECLARE_CONV_UNIT(LENGTH, BARLEYCORNS,          "$*0.9144/108",     "$/0.9144*108")
246     DECLARE_CONV_UNIT(LENGTH, CENTIMETERS,          "$/100",            "$*100")
247     DECLARE_CONV_UNIT(LENGTH, CHAINS_UK,            "$*20.1168",        "$/20.1168")
248     DECLARE_CONV_UNIT(LENGTH, CHI,                  "$/3",              "$*3")
249     DECLARE_CONV_UNIT(LENGTH, CHOU,                 "$*3600/33",        "$*33/3600")
250 //    DECLARE_CONV_UNIT(LENGTH, CHR,                  "$", "$")
251     DECLARE_CONV_UNIT(LENGTH, CUN,                  "$/30",             "$*30")
252     DECLARE_CONV_UNIT(LENGTH, FATHOMS,              "$*1.8288",         "$/1.8288")
253     DECLARE_CONV_UNIT(LENGTH, FATHOMS_HUNGARY,      "$*1.8964838",      "$/1.8964838")
254     DECLARE_CONV_UNIT(LENGTH, FEET,                 "$*0.3048",         "$/0.3048")
255     DECLARE_CONV_UNIT(LENGTH, FURLONGS,             "$*201.168",        "$/201.168")
256 //    DECLARE_CONV_UNIT(LENGTH, GAN,                  "$", "$")
257     DECLARE_CONV_UNIT(LENGTH, HANDS,                "$*0,1016",         "$/0,1016")
258 //    DECLARE_CONV_UNIT(LENGTH, HUNH,                 "$", "$")
259     DECLARE_CONV_UNIT(LENGTH, INCHES,               "$*0.0254",         "$/0.0254")
260 //    DECLARE_CONV_UNIT(LENGTH, JA,                   "$", "$")
261 //    DECLARE_CONV_UNIT(LENGTH, JEONG,                "$", "$")
262 //    DECLARE_CONV_UNIT(LENGTH, KABIET,               "$", "$")
263     DECLARE_CONV_UNIT(LENGTH, KEN,                  "$*60/33",          "$*33/60")
264 //    DECLARE_CONV_UNIT(LENGTH, KEUB,                 "$", "$")
265     DECLARE_CONV_UNIT(LENGTH, KILOMETERS,           "$*1000",           "$/1000")
266 //    DECLARE_CONV_UNIT(LENGTH, LAR,                  "$", "$")
267     DECLARE_CONV_UNIT(LENGTH, LIGHT_YEARS,          "$*9460730472580800", "$/9460730472580800")
268     DECLARE_CONV_UNIT(LENGTH, LINKS_UK,             "$*0.201168",       "$/0.201168")
269     DECLARE_CONV_UNIT(LENGTH, METERS,               "$",                "$")
270     DECLARE_CONV_UNIT(LENGTH, MICRONS,              "$*0.000001",       "$/0.000001")
271     DECLARE_CONV_UNIT(LENGTH, MILES,                "$*1609.344",       "$/1609.344")
272     DECLARE_CONV_UNIT(LENGTH, MILLIMETERS,          "$/1000",           "$*1000")
273     DECLARE_CONV_UNIT(LENGTH, NAUTICAL_MILES,       "$*1852",           "$/1852")
274 //    DECLARE_CONV_UNIT(LENGTH, NIEU,                 "$", "$")
275     DECLARE_CONV_UNIT(LENGTH, PARSECS,              "$*30856800000000000", "$/30856800000000000")
276     DECLARE_CONV_UNIT(LENGTH, PICAS,                "$*0.9144/216",     "$/0.9144*216")
277     DECLARE_CONV_UNIT(LENGTH, RODS,                 "$*5.0292",         "$/5.0292")
278 //    DECLARE_CONV_UNIT(LENGTH, RI_JAPAN,             "$", "$")
279 //    DECLARE_CONV_UNIT(LENGTH, RI_KOREA,             "$", "$")
280 //    DECLARE_CONV_UNIT(LENGTH, SAWK,                 "$", "$")
281 //    DECLARE_CONV_UNIT(LENGTH, SEN,                  "$", "$")
282     DECLARE_CONV_UNIT(LENGTH, SHAKU,                "$*10/33",          "$*33/10")
283     DECLARE_CONV_UNIT(LENGTH, SPAN,                 "$*0.9144/4",       "$*4/0.9144")
284     DECLARE_CONV_UNIT(LENGTH, SUN,                  "$*1/33",            "$*33")
285 //    DECLARE_CONV_UNIT(LENGTH, TSUEN,                "$", "$")
286 //    DECLARE_CONV_UNIT(LENGTH, VA,                   "$", "$")
287     DECLARE_CONV_UNIT(LENGTH, YARDS,                "$*0.9144",         "$/0.9144")
288 //    DECLARE_CONV_UNIT(LENGTH, YOTE,                 "$", "$")
289 //    DECLARE_CONV_UNIT(LENGTH, ZHANG,                "$", "$")
290     DECLARE_CONV_END
291 };
292 
293 /*
294     1 BTU/min = 17.5842642 W
295     1 Foot-pound/minute = 0.02259696580552333 W
296     1 hp = 745.69987158227022 W
297     1 KW = 1000 W
298     1 MW = 1000000 W
299 */
300 static const conv_t conv_POWER[] = {
301     DECLARE_CONV_UNIT(POWER, BTUS_PER_MINUTE, "$*17.5842642", "$/17.5842642")
302     DECLARE_CONV_UNIT(POWER, FPS_PER_MINUTE,  "$*0.02259696580552333", "$/0.02259696580552333")
303     DECLARE_CONV_UNIT(POWER, HORSEPOWER,      "$*745.69987158227022", "$/745.69987158227022")
304     DECLARE_CONV_UNIT(POWER, KILOWATTS,       "$*1000", "$/1000")
305     DECLARE_CONV_UNIT(POWER, MEGAWATTS,       "$*1000000", "$/1000000")
306     DECLARE_CONV_UNIT(POWER, WATTS,           "$", "$")
307     DECLARE_CONV_END
308 };
309 
310 /*
311     1 ATM   = 101325 Pa
312     1 BAR   = 100000 Pa
313     1 hPa   = 100 Pa
314     1 kPa   = 1000 Pa
315     1 mm HG = 133.322 Pa
316     1 psi   = 6894.757 Pa
317 */
318 static const conv_t conv_PRESSURE[] = {
319     DECLARE_CONV_UNIT(PRESSURE, ATMOSPHERES,   "$*101325",   "$/101325")
320     DECLARE_CONV_UNIT(PRESSURE, BARS,          "$*100000",   "$/100000")
321     DECLARE_CONV_UNIT(PRESSURE, HECTOPASCALS,  "$*100",      "$/100")
322     DECLARE_CONV_UNIT(PRESSURE, KILOPASCALS,   "$*1000",     "$/1000")
323     DECLARE_CONV_UNIT(PRESSURE, MM_OF_MERCURY, "$*133.322",  "$/133.322")
324     DECLARE_CONV_UNIT(PRESSURE, PASCALS,       "$",          "$")
325     DECLARE_CONV_UNIT(PRESSURE, PSI,           "$*6894.757", "$/6894.757")
326     DECLARE_CONV_END
327 };
328 
329 /*
330     1 day ....... = 86400 s
331     1 hour ...... = 3600 s
332     1 microsecond = 0.000001 s
333     1 millisecond = 0.001 s
334     1 nanosecond. = 0.000000001 s
335     1 minute .... = 60 s
336     1 week ...... = 669600 s
337 */
338 static const conv_t conv_TIME[] = {
339     DECLARE_CONV_UNIT(TIME, MINUTES,      "$*60",          "$/60")
340     DECLARE_CONV_UNIT(TIME, DAYS,         "$*86400",       "$/86400")
341     DECLARE_CONV_UNIT(TIME, HOURS,        "$*3600",        "$/3600")
342     DECLARE_CONV_UNIT(TIME, MILLISECONDS, "$*0.001",       "$/0.001")
343     DECLARE_CONV_UNIT(TIME, MICROSECONDS, "$*0.000001",    "$/0.000001")
344     DECLARE_CONV_UNIT(TIME, NANOSECONDS,  "$*0.000000001", "$/0.000000001")
345     DECLARE_CONV_UNIT(TIME, SECONDS,      "$",             "$")
346     DECLARE_CONV_UNIT(TIME, WEEKS,        "$*604800",      "$/604800")
347     DECLARE_CONV_UNIT(TIME, YEARS,        "$*31556952",    "$/31556952")
348     DECLARE_CONV_END
349 };
350 
351 /*
352     C = K - 273.15
353     F = K * 9/5 - 459.67
354     R = K * 9/5
355  */
356 static const conv_t conv_TEMPERATURE[] = {
357     DECLARE_CONV_UNIT(TEMPERATURE, CELSIUS,     "$+273.15",       "$-273.15")
358     DECLARE_CONV_UNIT(TEMPERATURE, FAHRENHEIT,  "($+459.67)*5/9", "$*9/5-459.67")
359     DECLARE_CONV_UNIT(TEMPERATURE, KELVIN,      "$",              "$")
360     DECLARE_CONV_UNIT(TEMPERATURE, RANKINE,     "$*5/9",          "$*9/5")
361     DECLARE_CONV_END
362 };
363 
364 /*
365     1 cm/s = 0.01 m/s
366     1 f/h  = 0.0000846666667 m/s
367     1 f/s  = 0.3048 m/s
368     1 Km/h = 10/36 m/s -> 0.27778 m/s
369     1 knot = 18.52/36 m/s -> 0.51444444 m/s
370     1 mach = 340.3 m/s
371     1 mph  = 0.44704 m/s
372 */
373 static const conv_t conv_VELOCITY[] = {
374     DECLARE_CONV_UNIT(VELOCITY, CMS_SECOND,         "$*.01",      "$/.01")
375     DECLARE_CONV_UNIT(VELOCITY, FEET_SECOND,        "$*.3048",    "$/.3048")
376     DECLARE_CONV_UNIT(VELOCITY, FEET_HOUR,          "$*.0000846666667", "$/.0000846666667")
377     DECLARE_CONV_UNIT(VELOCITY, KILOMETERS_HOUR,    "$*10/36",    "$*36/10")
378     DECLARE_CONV_UNIT(VELOCITY, KNOTS,              "$*18.52/36", "$*36/18.52")
379     DECLARE_CONV_UNIT(VELOCITY, MACH,               "$*340.3",    "$/340.3")
380     DECLARE_CONV_UNIT(VELOCITY, METERS_SECOND,      "$",          "$")
381     DECLARE_CONV_UNIT(VELOCITY, MILES_HOUR,         "$*.44704",   "$/.44704")
382     DECLARE_CONV_END
383 };
384 
385 /*
386     1 barrel uk ...... = 163.65924 l
387     1 barrel oil ..... = 158.987295 l
388     1 bun ............ =
389     1 bushel uk ...... = 36.36872 l
390     1 bushel us ...... = 35.23907017 l
391     1 cubic cm  ...... = 0.001 l
392     1 cubic feet ..... = 28.316846 l
393     1 cubic inch ..... = 0.016387064 l
394     1 cubic meter .... = 1000 l
395     1 cubic yard ..... = 764.554857 l
396     1 doe ............ =
397     1 fluid ounce uk   = 0.0284130625 l
398     1 fluid ounce us   = 0.0295735295625 l
399     1 gallon uk ...... = 4.54609 l
400     1 gallon dry us .. = 4.40488377086 l
401     1 gallon liquid us = 3.785411784 l
402     1 gou ............ = 0.1809 l
403     1 hop ............ =
404     1 icce ........... =
405     1 kwian .......... =
406     1 mal ............ =
407     1 milliliter ..... = 0.001 l
408     1 pint uk ........ = 0.56826125 l
409     1 pint dry us .... = 0.5506104713575 l
410     1 pint liquid us   = 0.473176473 l
411     1 quart uk ....... = 1.1365225 l
412     1 quart dry us ... = 1.101220942715 l
413     1 quart liquid us  = 0.946352946 l
414     1 seki ........... =
415     1 syou ........... =
416     1 tananloung ..... =
417     1 tang ........... =
418     1 to ............. = 18040 l
419 */
420 static const conv_t conv_VOLUME[] = {
421     DECLARE_CONV_UNIT(VOLUME, BARRELS_UK,           "$*163.65924",       "$/163.65924")
422     DECLARE_CONV_UNIT(VOLUME, BARRELS_OIL,          "$*158.987295",      "$/158.987295")
423 //    DECLARE_CONV_UNIT(VOLUME, BUN,                  "$", "$")
424     DECLARE_CONV_UNIT(VOLUME, BUSHELS_UK,           "$*36.36872",        "$/36.36872")
425     DECLARE_CONV_UNIT(VOLUME, BUSHELS_US,           "$*35.23907017",     "$/35.23907017")
426     DECLARE_CONV_UNIT(VOLUME, CUBIC_CENTIMETERS,    "$*0.001",           "$/0.001")
427     DECLARE_CONV_UNIT(VOLUME, CUBIC_FEET,           "$*28.316846",       "$/28.316846")
428     DECLARE_CONV_UNIT(VOLUME, CUBIC_INCHES,         "$*0.016387064",     "$/0.016387064")
429     DECLARE_CONV_UNIT(VOLUME, CUBIC_METERS,         "$*1000",            "$/1000")
430     DECLARE_CONV_UNIT(VOLUME, CUBIC_YARDS,          "$*764.554857",      "$/764.554857")
431 //    DECLARE_CONV_UNIT(VOLUME, DOE,                  "$", "$")
432     DECLARE_CONV_UNIT(VOLUME, FLUID_OUNCES_UK,      "$*0.0284130625",    "$/0.0284130625")
433     DECLARE_CONV_UNIT(VOLUME, FLUID_OUNCES_US,      "$*0.0295735295625", "$/0.0295735295625")
434     DECLARE_CONV_UNIT(VOLUME, GALLONS_UK,           "$*4.54609",         "$/4.54609")
435     DECLARE_CONV_UNIT(VOLUME, GALLONS_DRY_US,       "$*4.40488377086",   "$/4.40488377086")
436     DECLARE_CONV_UNIT(VOLUME, GALLONS_LIQUID_US,    "$*3.785411784",     "$/3.785411784")
437     DECLARE_CONV_UNIT(VOLUME, GOU,                  "$*0.1809",          "$/0.1809")
438 //    DECLARE_CONV_UNIT(VOLUME, HOP,                  "$", "$")
439 //    DECLARE_CONV_UNIT(VOLUME, ICCE,                 "$", "$")
440 //    DECLARE_CONV_UNIT(VOLUME, KWIAN,                "$", "$")
441     DECLARE_CONV_UNIT(VOLUME, LITERS,               "$",                 "$")
442 //    DECLARE_CONV_UNIT(VOLUME, MAL,                  "$", "$")
443     DECLARE_CONV_UNIT(VOLUME, MILLILITERS,          "$*0.001",           "$/0.001")
444     DECLARE_CONV_UNIT(VOLUME, PINTS_UK,             "$*0.56826125",      "$/0.56826125")
445     DECLARE_CONV_UNIT(VOLUME, PINTS_DRY_US,         "$*0.5506104713575", "$/0.5506104713575")
446     DECLARE_CONV_UNIT(VOLUME, PINTS_LIQUID_US,      "$*0.473176473",     "$/0.473176473")
447     DECLARE_CONV_UNIT(VOLUME, QUARTS_UK,            "$*1.1365225",       "$/1.1365225")
448     DECLARE_CONV_UNIT(VOLUME, QUARTS_DRY_US,        "$*1.101220942715",  "$/1.101220942715")
449     DECLARE_CONV_UNIT(VOLUME, QUARTS_LIQUID_US,     "$*0.946352946",     "$/0.946352946")
450 //    DECLARE_CONV_UNIT(VOLUME, SEKI,                 "$", "$")
451 //    DECLARE_CONV_UNIT(VOLUME, SYOU,                 "$", "$")
452 //    DECLARE_CONV_UNIT(VOLUME, TANANLOUNG,           "$", "$")
453 //    DECLARE_CONV_UNIT(VOLUME, TANG,                 "$", "$")
454     DECLARE_CONV_UNIT(VOLUME, TO,                   "$*18040",           "$/18040")
455     DECLARE_CONV_END
456 };
457 
458 /*
459     1 baht ............ = 12.244 g
460     1 carat ........... = 0.2 g
461     1 chung ........... =
462     1 don ............. =
463     1 geun ............ =
464     1 gwan ............ =
465     1 harb ............ =
466     1 jin china ....... =
467     1 jin taiwan ...... =
468     1 Kan ............. = 3750 g
469     1 Kilograms ....... = 1000 g
470     1 Kin ............. = 600 g
471     1 Liang China ..... =
472     1 Liang Taiwan .... =
473     1 monme ........... = 3.75 g
474     1 ounce avoirdupois = 28.349523125 g
475     1 ounce troy ...... = 31.1034768 g
476     1 pound ........... = 453.59237 g
477     1 quintal metric .. = 100000 g
478     1 saloung ......... =
479     1 stone ........... = 6350.29318 g
480     1 tamlung ......... =
481     1 ton ............. = 1000000 g
482     1 ton uk .......... = 1016046.9088 g  // long ton
483     1 ton us .......... = 907184.74 g     // short ton
484 */
485 static const conv_t conv_WEIGHT[] = {
486     DECLARE_CONV_UNIT(WEIGHT, BAHT,                 "$*12.244",       "$/12.244")
487     DECLARE_CONV_UNIT(WEIGHT, CARATS,               "$*0.2",          "$/0.2")
488 //    DECLARE_CONV_UNIT(WEIGHT, CHUNG,                "$", "$")
489 //    DECLARE_CONV_UNIT(WEIGHT, DON,                  "$", "$")
490 //    DECLARE_CONV_UNIT(WEIGHT, GEUN,                 "$", "$")
491     DECLARE_CONV_UNIT(WEIGHT, GRAMS,                "$",              "$")
492 //    DECLARE_CONV_UNIT(WEIGHT, GWAN,                 "$", "$")
493 //    DECLARE_CONV_UNIT(WEIGHT, HARB,                 "$", "$")
494 //    DECLARE_CONV_UNIT(WEIGHT, JIN_CHINA,            "$", "$")
495 //    DECLARE_CONV_UNIT(WEIGHT, JIN_TAIWAN,           "$", "$")
496     DECLARE_CONV_UNIT(WEIGHT, KAN,                  "$*3750",         "$/3750")
497     DECLARE_CONV_UNIT(WEIGHT, KILOGRAMS,            "$*1000",         "$/1000")
498     DECLARE_CONV_UNIT(WEIGHT, KIN,                  "$*600",          "$/600")
499 //    DECLARE_CONV_UNIT(WEIGHT, LIANG_CHINA,          "$", "$")
500 //    DECLARE_CONV_UNIT(WEIGHT, LIANG_TAIWAN,         "$", "$")
501     DECLARE_CONV_UNIT(WEIGHT, MONME,                "$*3.75",         "$/3.75")
502     DECLARE_CONV_UNIT(WEIGHT, OUNCES_AVOIRDUPOIS,   "$*28.349523125", "$/28.349523125")
503     DECLARE_CONV_UNIT(WEIGHT, OUNCES_TROY,          "$*31.1034768",   "$/31.1034768")
504     DECLARE_CONV_UNIT(WEIGHT, POUNDS,               "$*453.59237",    "$/453.59237")
505     DECLARE_CONV_UNIT(WEIGHT, QUINTAL_METRIC,       "$*100000",       "$/100000")
506 //    DECLARE_CONV_UNIT(WEIGHT, SALOUNG,              "$", "$")
507     DECLARE_CONV_UNIT(WEIGHT, STONES,               "$*6350.29318",    "$/6350.29318")
508 //    DECLARE_CONV_UNIT(WEIGHT, TAMLUNG,              "$", "$")
509     DECLARE_CONV_UNIT(WEIGHT, TONNES,               "$*1000000",       "$/1000000")
510     DECLARE_CONV_UNIT(WEIGHT, TONS_UK,              "$*1016046.9088",  "$/1016046.9088")
511     DECLARE_CONV_UNIT(WEIGHT, TONS_US,              "$*907184.74",     "$/907184.74")
512     DECLARE_CONV_END
513 };
514 
515 static const conv_category_t conv_table[] = {
516     DECLARE_CONV_CAT(ANGLE)
517     DECLARE_CONV_CAT(AREA)
518     DECLARE_CONV_CAT(CONSUMPTION)
519     DECLARE_CONV_CAT(CURRENCY)
520     DECLARE_CONV_CAT(ENERGY)
521     DECLARE_CONV_CAT(LENGTH)
522     DECLARE_CONV_CAT(POWER)
523     DECLARE_CONV_CAT(PRESSURE)
524     DECLARE_CONV_CAT(TIME)
525     DECLARE_CONV_CAT(TEMPERATURE)
526     DECLARE_CONV_CAT(VELOCITY)
527     DECLARE_CONV_CAT(VOLUME)
528     DECLARE_CONV_CAT(WEIGHT)
529 };
530 
531 void ConvExecute(HWND hWnd)
532 {
533     DWORD         c_cat = (DWORD)SendDlgItemMessage(hWnd, IDC_COMBO_CATEGORY, CB_GETCURSEL, 0, 0);
534     const conv_t *items = NULL;
535     DWORD         from  = SendDlgItemMessage(hWnd, IDC_COMBO_FROM, CB_GETCURSEL, 0, 0);
536     DWORD         to    = SendDlgItemMessage(hWnd, IDC_COMBO_TO,   CB_GETCURSEL, 0, 0);
537     TCHAR         txt_cb[128];
538     TCHAR         txt[128];
539     const conv_t *item;
540 
541     /* do nothing if the indexes point to the same unit */
542     if (from == to)
543         return;
544 
545     /* Search correct category, since it can be sorted too */
546     SendDlgItemMessage(hWnd, IDC_COMBO_CATEGORY, CB_GETLBTEXT, c_cat, (LPARAM)txt_cb);
547     for (c_cat=0; c_cat < SIZEOF(conv_table); c_cat++) {
548         LoadString(calc.hInstance, conv_table[c_cat].category, txt, SIZEOF(txt));
549         if (!_tcscmp(txt_cb, txt)) {
550             items = conv_table[c_cat].items;
551             break;
552         }
553     }
554 
555     /* The units can be sorted, so I must search the exact match */
556     item = items;
557     SendDlgItemMessage(hWnd, IDC_COMBO_FROM, CB_GETLBTEXT, from, (LPARAM)txt_cb);
558     while (item->unit) {
559         LoadString(calc.hInstance, item->unit, txt, SIZEOF(txt));
560         if (!_tcscmp(txt_cb, txt)) {
561             from = item-items;
562             break;
563         }
564         item++;
565     }
566     SendDlgItemMessage(hWnd, IDC_COMBO_TO, CB_GETLBTEXT, to, (LPARAM)txt_cb);
567     item = items;
568     while (item->unit) {
569         LoadString(calc.hInstance, item->unit, txt, SIZEOF(txt));
570         if (!_tcscmp(txt_cb, txt)) {
571             to = item-items;
572             break;
573         }
574         item++;
575     }
576 
577     calc.Convert[0].data = (char *)items[from].formula_from;
578     calc.Convert[1].data = (char *)items[to].formula_to;
579     calc.Convert[0].wm_msg = WM_HANDLE_FROM;
580     calc.Convert[1].wm_msg = WM_HANDLE_TO;
581     PostMessage(hWnd, WM_START_CONV, 0, MAKELPARAM(0, WM_HANDLE_FROM));
582 }
583 
584 void ConvAdjust(HWND hWnd, int n_cat)
585 {
586     TCHAR         txt[128];
587     TCHAR         txt_cat[128];
588     HWND          hFromWnd = GetDlgItem(hWnd, IDC_COMBO_FROM);
589     HWND          hToWnd   = GetDlgItem(hWnd, IDC_COMBO_TO);
590     const conv_t *item;
591     unsigned int  n;
592 
593     SendDlgItemMessage(hWnd, IDC_COMBO_CATEGORY, CB_GETLBTEXT, n_cat, (LPARAM)txt_cat);
594     for (n=0; n<SIZEOF(conv_table); n++) {
595         item = conv_table[n].items;
596         LoadString(calc.hInstance, conv_table[n].category, txt, SIZEOF(txt));
597         if (!_tcscmp(txt_cat, txt))
598             break;
599     }
600 
601     SendMessage(hFromWnd, CB_RESETCONTENT, 0, 0);
602     SendMessage(hToWnd,   CB_RESETCONTENT, 0, 0);
603     while (item->unit) {
604         LoadString(calc.hInstance, item->unit, txt, SIZEOF(txt));
605         SendMessage(hFromWnd, CB_ADDSTRING, 0, (LPARAM)txt);
606         SendMessage(hToWnd,   CB_ADDSTRING, 0, (LPARAM)txt);
607         item++;
608     }
609     SendMessage(hFromWnd, CB_SETCURSEL, 0, 0);
610     SendMessage(hToWnd,   CB_SETCURSEL, 0, 0);
611 }
612 
613 void ConvInit(HWND hWnd)
614 {
615     HWND         hCatWnd = GetDlgItem(hWnd, IDC_COMBO_CATEGORY);
616     TCHAR        txt[128];
617     unsigned int n;
618 
619     /* Fill category combo */
620     for (n=0; n<SIZEOF(conv_table); n++) {
621         LoadString(calc.hInstance, conv_table[n].category, txt, SIZEOF(txt));
622         SendMessage(hCatWnd, CB_ADDSTRING, 0, (LPARAM)txt);
623     }
624     SendMessage(hCatWnd, CB_SETCURSEL, 0, 0);
625     ConvAdjust(hWnd, 0);
626 }
627 
628