xref: /reactos/base/applications/calc/convert.c (revision 845faec4)
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, DEUTSCHE_MARK,      "$/1,95583", "$*1,95583")
148     DECLARE_CONV_UNIT(CURRENCY, DUTCH_GUILDER,      "$/2,20371", "$*2,20371")
149     DECLARE_CONV_UNIT(CURRENCY, ESTONIAN_KROON,     "$/15,6466", "$*15,6466")
150     DECLARE_CONV_UNIT(CURRENCY, EURO,               "$",         "$")
151     DECLARE_CONV_UNIT(CURRENCY, FINNISH_MARKKA,     "$/5,94573", "$*5,94573")
152     DECLARE_CONV_UNIT(CURRENCY, FRENCH_FRANC,       "$/6,55957", "$*6,55957")
153     DECLARE_CONV_UNIT(CURRENCY, GREEK_DRACHMA,      "$/340,751", "$*340,751")
154     DECLARE_CONV_UNIT(CURRENCY, IRISH_POUND,        "$/0,787564","$*0,787564")
155     DECLARE_CONV_UNIT(CURRENCY, ITALIAN_LIRA,       "$/1936.27", "$*1936.27")
156     DECLARE_CONV_UNIT(CURRENCY, LATVIAN_LATS,       "$/0,7028",  "$*0,7028")
157     DECLARE_CONV_UNIT(CURRENCY, LITHUANIAN_LITAS,   "$/3,45280", "$*3,45280")
158     DECLARE_CONV_UNIT(CURRENCY, LUXEMBOURG_FRANC,   "$/40,3399", "$*40,3399")
159     DECLARE_CONV_UNIT(CURRENCY, MALTESE_LIRA,       "$/0.42930", "$*0.42930")
160     DECLARE_CONV_UNIT(CURRENCY, PORTOGUESE_ESCUDO,  "$/200,482", "$*200,482")
161     DECLARE_CONV_UNIT(CURRENCY, SLOVAK_KORUNA,      "$/30,126",  "$*30,126")
162     DECLARE_CONV_UNIT(CURRENCY, SLOVENIAN_TOLAR,    "$/239,640", "$*239,640")
163     DECLARE_CONV_UNIT(CURRENCY, SPANISH_PESETA,     "$/166,386", "$*166,386")
164     DECLARE_CONV_END
165 };
166 
167 /*
168     1 cal15 .... = 4.1855 J
169     1 BTU ...... = 1055.056 J
170     1 ERG ...... = 0.0000001 J
171     1 EV ....... = 0.000000000000000000160217653 J
172     1 Foot-Pound = 1.3558179483314004 J
173     1 IT calorie = 4.1868 J
174     1 KCa ...... = 4186.8 J
175     1 KJ ....... = 1000 J
176     1 KWh ...... = 3600 J
177     1 IUNS ..... = 4.182 J
178     1 calth .... = 4.184 J
179 */
180 static const conv_t conv_ENERGY[] = {
181     DECLARE_CONV_UNIT(ENERGY, 15_C_CALORIES,        "$*4.1855",   "$/4.1855")
182     DECLARE_CONV_UNIT(ENERGY, BTUS,                 "$*1055.056", "$/1055.056")
183     DECLARE_CONV_UNIT(ENERGY, ERGS,                 "$*.0000001", "$/.0000001")
184     DECLARE_CONV_UNIT(ENERGY, EVS,                  "$*.000000000000000000160217653", "$/.000000000000000000160217653")
185     DECLARE_CONV_UNIT(ENERGY, FOOT_POUNDS,          "$*1.3558179483314004",   "$/1.3558179483314004")
186     DECLARE_CONV_UNIT(ENERGY, IT_CALORIES,          "$*4.1868",   "$/4.1868")
187     DECLARE_CONV_UNIT(ENERGY, IT_KILOCALORIES,      "$*4186.8",   "$/4186.8")
188     DECLARE_CONV_UNIT(ENERGY, JOULES,               "$",          "$")
189     DECLARE_CONV_UNIT(ENERGY, KILOJOULES,           "$*1000",     "$/1000")
190     DECLARE_CONV_UNIT(ENERGY, KILOWATT_HOURS,       "$*3600",     "$/3600")
191     DECLARE_CONV_UNIT(ENERGY, NUTRITION_CALORIES,   "$*4.182",    "$/4.182")
192     DECLARE_CONV_UNIT(ENERGY, TH_CALORIES,          "$*4.184",    "$/4.184")
193     DECLARE_CONV_END
194 };
195 
196 /*
197     1 angstrom ....... = 0.0000000001 m
198     1 astronomical unit= 149598000000 m
199     1 barleycorn ..... = 1/3 inch = 0.9144/108 m
200     1 cm ............. = 1/100 m
201     1 chain uk ....... = 22 yards = 22*0.9144 m
202     1 chi ............ = 1/3 m
203     1 chou ........... = 3600/33 m
204     1 chr ............ =
205     1 cun ............ = 1/10 chi = 1/30 m
206     1 fathom ......... = 2 yard = 2*0.9144 m
207     1 fathom ungary .. = 1.8964838 m (fixed)
208     1 feet ........... = 12 inch = 0.9144/3 m
209     1 furlong ........ = 10 chains = 220*0.9144 m
210     1 gan ............ =
211     1 hand ........... = 4 inches = 0.9144/9 m
212     1 hunh ........... =
213     1 inch ........... = yard/36 = 0.9144/36 m
214     1 ja ............. =
215     1 jeong .......... =
216     1 kabiet ......... =
217     1 ken ............ = 60/33 m
218     1 keub ........... =
219     1 km ............. = 1000 m
220     1 lar ............ =
221     1 light year ..... = 9460730472580800 m
222     1 link uk ........ = 0.01 chains = 0.22*0.9144 m
223     1 micron ......... = 0.000001 m
224     1 mile ........... = 1760 yards = 1609.344 m
225     1 millimeter ..... = 1/1000 m
226     1 nautical mile .. = 1852 m
227     1 nieu ........... =
228     1 parsec ......... = 30856800000000000 m
229     1 pica ........... = yard/216 = 0.9144/216 m
230     1 ri japan ....... =
231     1 ri korea ....... =
232     1 rod ............ = 5.0292 m
233     1 sawk ........... =
234     1 sen ............ =
235     1 shaku .......... = 10/33 m
236     1 span ........... = 9 inches = 0.9144/4 m
237     1 sun ............ = 1/33 m
238     1 tsuen .......... =
239     1 va ............. =
240     1 yard ........... = 0.9144 m
241     1 yote ........... =
242     1 zhang .......... =
243 */
244 static const conv_t conv_LENGTH[] = {
245     DECLARE_CONV_UNIT(LENGTH, ANGSTROMS,            "$*0.0000000001",   "$/0.0000000001")
246     DECLARE_CONV_UNIT(LENGTH, ASTRONOMICAL_UNITS,   "$*149598000000",   "$/149598000000")
247     DECLARE_CONV_UNIT(LENGTH, BARLEYCORNS,          "$*0.9144/108",     "$/0.9144*108")
248     DECLARE_CONV_UNIT(LENGTH, CENTIMETERS,          "$/100",            "$*100")
249     DECLARE_CONV_UNIT(LENGTH, CHAINS_UK,            "$*20.1168",        "$/20.1168")
250     DECLARE_CONV_UNIT(LENGTH, CHI,                  "$/3",              "$*3")
251     DECLARE_CONV_UNIT(LENGTH, CHOU,                 "$*3600/33",        "$*33/3600")
252 //    DECLARE_CONV_UNIT(LENGTH, CHR,                  "$", "$")
253     DECLARE_CONV_UNIT(LENGTH, CUN,                  "$/30",             "$*30")
254     DECLARE_CONV_UNIT(LENGTH, FATHOMS,              "$*1.8288",         "$/1.8288")
255     DECLARE_CONV_UNIT(LENGTH, FATHOMS_HUNGARY,      "$*1.8964838",      "$/1.8964838")
256     DECLARE_CONV_UNIT(LENGTH, FEET,                 "$*0.3048",         "$/0.3048")
257     DECLARE_CONV_UNIT(LENGTH, FURLONGS,             "$*201.168",        "$/201.168")
258 //    DECLARE_CONV_UNIT(LENGTH, GAN,                  "$", "$")
259     DECLARE_CONV_UNIT(LENGTH, HANDS,                "$*0,1016",         "$/0,1016")
260 //    DECLARE_CONV_UNIT(LENGTH, HUNH,                 "$", "$")
261     DECLARE_CONV_UNIT(LENGTH, INCHES,               "$*0.0254",         "$/0.0254")
262 //    DECLARE_CONV_UNIT(LENGTH, JA,                   "$", "$")
263 //    DECLARE_CONV_UNIT(LENGTH, JEONG,                "$", "$")
264 //    DECLARE_CONV_UNIT(LENGTH, KABIET,               "$", "$")
265     DECLARE_CONV_UNIT(LENGTH, KEN,                  "$*60/33",          "$*33/60")
266 //    DECLARE_CONV_UNIT(LENGTH, KEUB,                 "$", "$")
267     DECLARE_CONV_UNIT(LENGTH, KILOMETERS,           "$*1000",           "$/1000")
268 //    DECLARE_CONV_UNIT(LENGTH, LAR,                  "$", "$")
269     DECLARE_CONV_UNIT(LENGTH, LIGHT_YEARS,          "$*9460730472580800", "$/9460730472580800")
270     DECLARE_CONV_UNIT(LENGTH, LINKS_UK,             "$*0.201168",       "$/0.201168")
271     DECLARE_CONV_UNIT(LENGTH, METERS,               "$",                "$")
272     DECLARE_CONV_UNIT(LENGTH, MICRONS,              "$*0.000001",       "$/0.000001")
273     DECLARE_CONV_UNIT(LENGTH, MILES,                "$*1609.344",       "$/1609.344")
274     DECLARE_CONV_UNIT(LENGTH, MILLIMETERS,          "$/1000",           "$*1000")
275     DECLARE_CONV_UNIT(LENGTH, NAUTICAL_MILES,       "$*1852",           "$/1852")
276 //    DECLARE_CONV_UNIT(LENGTH, NIEU,                 "$", "$")
277     DECLARE_CONV_UNIT(LENGTH, PARSECS,              "$*30856800000000000", "$/30856800000000000")
278     DECLARE_CONV_UNIT(LENGTH, PICAS,                "$*0.9144/216",     "$/0.9144*216")
279     DECLARE_CONV_UNIT(LENGTH, RODS,                 "$*5.0292",         "$/5.0292")
280 //    DECLARE_CONV_UNIT(LENGTH, RI_JAPAN,             "$", "$")
281 //    DECLARE_CONV_UNIT(LENGTH, RI_KOREA,             "$", "$")
282 //    DECLARE_CONV_UNIT(LENGTH, SAWK,                 "$", "$")
283 //    DECLARE_CONV_UNIT(LENGTH, SEN,                  "$", "$")
284     DECLARE_CONV_UNIT(LENGTH, SHAKU,                "$*10/33",          "$*33/10")
285     DECLARE_CONV_UNIT(LENGTH, SPAN,                 "$*0.9144/4",       "$*4/0.9144")
286     DECLARE_CONV_UNIT(LENGTH, SUN,                  "$*1/33",            "$*33")
287 //    DECLARE_CONV_UNIT(LENGTH, TSUEN,                "$", "$")
288 //    DECLARE_CONV_UNIT(LENGTH, VA,                   "$", "$")
289     DECLARE_CONV_UNIT(LENGTH, YARDS,                "$*0.9144",         "$/0.9144")
290 //    DECLARE_CONV_UNIT(LENGTH, YOTE,                 "$", "$")
291 //    DECLARE_CONV_UNIT(LENGTH, ZHANG,                "$", "$")
292     DECLARE_CONV_END
293 };
294 
295 /*
296     1 BTU/min = 17.5842642 W
297     1 Foot-pound/minute = 0.02259696580552333 W
298     1 hp = 745.69987158227022 W
299     1 KW = 1000 W
300     1 MW = 1000000 W
301 */
302 static const conv_t conv_POWER[] = {
303     DECLARE_CONV_UNIT(POWER, BTUS_PER_MINUTE, "$*17.5842642", "$/17.5842642")
304     DECLARE_CONV_UNIT(POWER, FPS_PER_MINUTE,  "$*0.02259696580552333", "$/0.02259696580552333")
305     DECLARE_CONV_UNIT(POWER, HORSEPOWER,      "$*745.69987158227022", "$/745.69987158227022")
306     DECLARE_CONV_UNIT(POWER, KILOWATTS,       "$*1000", "$/1000")
307     DECLARE_CONV_UNIT(POWER, MEGAWATTS,       "$*1000000", "$/1000000")
308     DECLARE_CONV_UNIT(POWER, WATTS,           "$", "$")
309     DECLARE_CONV_END
310 };
311 
312 /*
313     1 ATM   = 101325 Pa
314     1 BAR   = 100000 Pa
315     1 hPa   = 100 Pa
316     1 kPa   = 1000 Pa
317     1 mm HG = 133.322 Pa
318     1 psi   = 6894.757 Pa
319 */
320 static const conv_t conv_PRESSURE[] = {
321     DECLARE_CONV_UNIT(PRESSURE, ATMOSPHERES,   "$*101325",   "$/101325")
322     DECLARE_CONV_UNIT(PRESSURE, BARS,          "$*100000",   "$/100000")
323     DECLARE_CONV_UNIT(PRESSURE, HECTOPASCALS,  "$*100",      "$/100")
324     DECLARE_CONV_UNIT(PRESSURE, KILOPASCALS,   "$*1000",     "$/1000")
325     DECLARE_CONV_UNIT(PRESSURE, MM_OF_MERCURY, "$*133.322",  "$/133.322")
326     DECLARE_CONV_UNIT(PRESSURE, PASCALS,       "$",          "$")
327     DECLARE_CONV_UNIT(PRESSURE, PSI,           "$*6894.757", "$/6894.757")
328     DECLARE_CONV_END
329 };
330 
331 /*
332     1 day ....... = 86400 s
333     1 hour ...... = 3600 s
334     1 microsecond = 0.000001 s
335     1 millisecond = 0.001 s
336     1 nanosecond. = 0.000000001 s
337     1 minute .... = 60 s
338     1 week ...... = 669600 s
339 */
340 static const conv_t conv_TIME[] = {
341     DECLARE_CONV_UNIT(TIME, MINUTES,      "$*60",          "$/60")
342     DECLARE_CONV_UNIT(TIME, DAYS,         "$*86400",       "$/86400")
343     DECLARE_CONV_UNIT(TIME, HOURS,        "$*3600",        "$/3600")
344     DECLARE_CONV_UNIT(TIME, MILLISECONDS, "$*0.001",       "$/0.001")
345     DECLARE_CONV_UNIT(TIME, MICROSECONDS, "$*0.000001",    "$/0.000001")
346     DECLARE_CONV_UNIT(TIME, NANOSECONDS,  "$*0.000000001", "$/0.000000001")
347     DECLARE_CONV_UNIT(TIME, SECONDS,      "$",             "$")
348     DECLARE_CONV_UNIT(TIME, WEEKS,        "$*604800",      "$/604800")
349     DECLARE_CONV_UNIT(TIME, YEARS,        "$*31556952",    "$/31556952")
350     DECLARE_CONV_END
351 };
352 
353 /*
354     C = K - 273.15
355     F = K * 9/5 - 459.67
356     R = K * 9/5
357  */
358 static const conv_t conv_TEMPERATURE[] = {
359     DECLARE_CONV_UNIT(TEMPERATURE, CELSIUS,     "$+273.15",       "$-273.15")
360     DECLARE_CONV_UNIT(TEMPERATURE, FAHRENHEIT,  "($+459.67)*5/9", "$*9/5-459.67")
361     DECLARE_CONV_UNIT(TEMPERATURE, KELVIN,      "$",              "$")
362     DECLARE_CONV_UNIT(TEMPERATURE, RANKINE,     "$*5/9",          "$*9/5")
363     DECLARE_CONV_END
364 };
365 
366 /*
367     1 cm/s = 0.01 m/s
368     1 f/h  = 0.0000846666667 m/s
369     1 f/s  = 0.3048 m/s
370     1 Km/h = 10/36 m/s -> 0.27778 m/s
371     1 knot = 18.52/36 m/s -> 0.51444444 m/s
372     1 mach = 340.3 m/s
373     1 mph  = 0.44704 m/s
374 */
375 static const conv_t conv_VELOCITY[] = {
376     DECLARE_CONV_UNIT(VELOCITY, CMS_SECOND,         "$*.01",      "$/.01")
377     DECLARE_CONV_UNIT(VELOCITY, FEET_SECOND,        "$*.3048",    "$/.3048")
378     DECLARE_CONV_UNIT(VELOCITY, FEET_HOUR,          "$*.0000846666667", "$/.0000846666667")
379     DECLARE_CONV_UNIT(VELOCITY, KILOMETERS_HOUR,    "$*10/36",    "$*36/10")
380     DECLARE_CONV_UNIT(VELOCITY, KNOTS,              "$*18.52/36", "$*36/18.52")
381     DECLARE_CONV_UNIT(VELOCITY, MACH,               "$*340.3",    "$/340.3")
382     DECLARE_CONV_UNIT(VELOCITY, METERS_SECOND,      "$",          "$")
383     DECLARE_CONV_UNIT(VELOCITY, MILES_HOUR,         "$*.44704",   "$/.44704")
384     DECLARE_CONV_END
385 };
386 
387 /*
388     1 barrel uk ...... = 163.65924 l
389     1 barrel oil ..... = 158.987295 l
390     1 bun ............ =
391     1 bushel uk ...... = 36.36872 l
392     1 bushel us ...... = 35.23907017 l
393     1 cubic cm  ...... = 0.001 l
394     1 cubic feet ..... = 28.316846 l
395     1 cubic inch ..... = 0.016387064 l
396     1 cubic meter .... = 1000 l
397     1 cubic yard ..... = 764.554857 l
398     1 doe ............ =
399     1 fluid ounce uk   = 0.0284130625 l
400     1 fluid ounce us   = 0.0295735295625 l
401     1 gallon uk ...... = 4.54609 l
402     1 gallon dry us .. = 4.40488377086 l
403     1 gallon liquid us = 3.785411784 l
404     1 gou ............ = 0.1809 l
405     1 hop ............ =
406     1 icce ........... =
407     1 kwian .......... =
408     1 mal ............ =
409     1 milliliter ..... = 0.001 l
410     1 pint uk ........ = 0.56826125 l
411     1 pint dry us .... = 0.5506104713575 l
412     1 pint liquid us   = 0.473176473 l
413     1 quart uk ....... = 1.1365225 l
414     1 quart dry us ... = 1.101220942715 l
415     1 quart liquid us  = 0.946352946 l
416     1 seki ........... =
417     1 syou ........... =
418     1 tananloung ..... =
419     1 tang ........... =
420     1 to ............. = 18040 l
421 */
422 static const conv_t conv_VOLUME[] = {
423     DECLARE_CONV_UNIT(VOLUME, BARRELS_UK,           "$*163.65924",       "$/163.65924")
424     DECLARE_CONV_UNIT(VOLUME, BARRELS_OIL,          "$*158.987295",      "$/158.987295")
425 //    DECLARE_CONV_UNIT(VOLUME, BUN,                  "$", "$")
426     DECLARE_CONV_UNIT(VOLUME, BUSHELS_UK,           "$*36.36872",        "$/36.36872")
427     DECLARE_CONV_UNIT(VOLUME, BUSHELS_US,           "$*35.23907017",     "$/35.23907017")
428     DECLARE_CONV_UNIT(VOLUME, CUBIC_CENTIMETERS,    "$*0.001",           "$/0.001")
429     DECLARE_CONV_UNIT(VOLUME, CUBIC_FEET,           "$*28.316846",       "$/28.316846")
430     DECLARE_CONV_UNIT(VOLUME, CUBIC_INCHES,         "$*0.016387064",     "$/0.016387064")
431     DECLARE_CONV_UNIT(VOLUME, CUBIC_METERS,         "$*1000",            "$/1000")
432     DECLARE_CONV_UNIT(VOLUME, CUBIC_YARDS,          "$*764.554857",      "$/764.554857")
433 //    DECLARE_CONV_UNIT(VOLUME, DOE,                  "$", "$")
434     DECLARE_CONV_UNIT(VOLUME, FLUID_OUNCES_UK,      "$*0.0284130625",    "$/0.0284130625")
435     DECLARE_CONV_UNIT(VOLUME, FLUID_OUNCES_US,      "$*0.0295735295625", "$/0.0295735295625")
436     DECLARE_CONV_UNIT(VOLUME, GALLONS_UK,           "$*4.54609",         "$/4.54609")
437     DECLARE_CONV_UNIT(VOLUME, GALLONS_DRY_US,       "$*4.40488377086",   "$/4.40488377086")
438     DECLARE_CONV_UNIT(VOLUME, GALLONS_LIQUID_US,    "$*3.785411784",     "$/3.785411784")
439     DECLARE_CONV_UNIT(VOLUME, GOU,                  "$*0.1809",          "$/0.1809")
440 //    DECLARE_CONV_UNIT(VOLUME, HOP,                  "$", "$")
441 //    DECLARE_CONV_UNIT(VOLUME, ICCE,                 "$", "$")
442 //    DECLARE_CONV_UNIT(VOLUME, KWIAN,                "$", "$")
443     DECLARE_CONV_UNIT(VOLUME, LITERS,               "$",                 "$")
444 //    DECLARE_CONV_UNIT(VOLUME, MAL,                  "$", "$")
445     DECLARE_CONV_UNIT(VOLUME, MILLILITERS,          "$*0.001",           "$/0.001")
446     DECLARE_CONV_UNIT(VOLUME, PINTS_UK,             "$*0.56826125",      "$/0.56826125")
447     DECLARE_CONV_UNIT(VOLUME, PINTS_DRY_US,         "$*0.5506104713575", "$/0.5506104713575")
448     DECLARE_CONV_UNIT(VOLUME, PINTS_LIQUID_US,      "$*0.473176473",     "$/0.473176473")
449     DECLARE_CONV_UNIT(VOLUME, QUARTS_UK,            "$*1.1365225",       "$/1.1365225")
450     DECLARE_CONV_UNIT(VOLUME, QUARTS_DRY_US,        "$*1.101220942715",  "$/1.101220942715")
451     DECLARE_CONV_UNIT(VOLUME, QUARTS_LIQUID_US,     "$*0.946352946",     "$/0.946352946")
452 //    DECLARE_CONV_UNIT(VOLUME, SEKI,                 "$", "$")
453 //    DECLARE_CONV_UNIT(VOLUME, SYOU,                 "$", "$")
454 //    DECLARE_CONV_UNIT(VOLUME, TANANLOUNG,           "$", "$")
455 //    DECLARE_CONV_UNIT(VOLUME, TANG,                 "$", "$")
456     DECLARE_CONV_UNIT(VOLUME, TO,                   "$*18040",           "$/18040")
457     DECLARE_CONV_END
458 };
459 
460 /*
461     1 baht ............ = 12.244 g
462     1 carat ........... = 0.2 g
463     1 chung ........... =
464     1 don ............. =
465     1 geun ............ =
466     1 gwan ............ =
467     1 harb ............ =
468     1 jin china ....... =
469     1 jin taiwan ...... =
470     1 Kan ............. = 3750 g
471     1 Kilograms ....... = 1000 g
472     1 Kin ............. = 600 g
473     1 Liang China ..... =
474     1 Liang Taiwan .... =
475     1 monme ........... = 3.75 g
476     1 ounce avoirdupois = 28.349523125 g
477     1 ounce troy ...... = 31.1034768 g
478     1 pound ........... = 453.59237 g
479     1 quintal metric .. = 100000 g
480     1 saloung ......... =
481     1 stone ........... = 6350.29318 g
482     1 tamlung ......... =
483     1 ton ............. = 1000000 g
484     1 ton uk .......... = 1016046.9088 g  // long ton
485     1 ton us .......... = 907184.74 g     // short ton
486 */
487 static const conv_t conv_WEIGHT[] = {
488     DECLARE_CONV_UNIT(WEIGHT, BAHT,                 "$*12.244",       "$/12.244")
489     DECLARE_CONV_UNIT(WEIGHT, CARATS,               "$*0.2",          "$/0.2")
490 //    DECLARE_CONV_UNIT(WEIGHT, CHUNG,                "$", "$")
491 //    DECLARE_CONV_UNIT(WEIGHT, DON,                  "$", "$")
492 //    DECLARE_CONV_UNIT(WEIGHT, GEUN,                 "$", "$")
493     DECLARE_CONV_UNIT(WEIGHT, GRAMS,                "$",              "$")
494 //    DECLARE_CONV_UNIT(WEIGHT, GWAN,                 "$", "$")
495 //    DECLARE_CONV_UNIT(WEIGHT, HARB,                 "$", "$")
496 //    DECLARE_CONV_UNIT(WEIGHT, JIN_CHINA,            "$", "$")
497 //    DECLARE_CONV_UNIT(WEIGHT, JIN_TAIWAN,           "$", "$")
498     DECLARE_CONV_UNIT(WEIGHT, KAN,                  "$*3750",         "$/3750")
499     DECLARE_CONV_UNIT(WEIGHT, KILOGRAMS,            "$*1000",         "$/1000")
500     DECLARE_CONV_UNIT(WEIGHT, KIN,                  "$*600",          "$/600")
501 //    DECLARE_CONV_UNIT(WEIGHT, LIANG_CHINA,          "$", "$")
502 //    DECLARE_CONV_UNIT(WEIGHT, LIANG_TAIWAN,         "$", "$")
503     DECLARE_CONV_UNIT(WEIGHT, MONME,                "$*3.75",         "$/3.75")
504     DECLARE_CONV_UNIT(WEIGHT, OUNCES_AVOIRDUPOIS,   "$*28.349523125", "$/28.349523125")
505     DECLARE_CONV_UNIT(WEIGHT, OUNCES_TROY,          "$*31.1034768",   "$/31.1034768")
506     DECLARE_CONV_UNIT(WEIGHT, POUNDS,               "$*453.59237",    "$/453.59237")
507     DECLARE_CONV_UNIT(WEIGHT, QUINTAL_METRIC,       "$*100000",       "$/100000")
508 //    DECLARE_CONV_UNIT(WEIGHT, SALOUNG,              "$", "$")
509     DECLARE_CONV_UNIT(WEIGHT, STONES,               "$*6350.29318",    "$/6350.29318")
510 //    DECLARE_CONV_UNIT(WEIGHT, TAMLUNG,              "$", "$")
511     DECLARE_CONV_UNIT(WEIGHT, TONNES,               "$*1000000",       "$/1000000")
512     DECLARE_CONV_UNIT(WEIGHT, TONS_UK,              "$*1016046.9088",  "$/1016046.9088")
513     DECLARE_CONV_UNIT(WEIGHT, TONS_US,              "$*907184.74",     "$/907184.74")
514     DECLARE_CONV_END
515 };
516 
517 static const conv_category_t conv_table[] = {
518     DECLARE_CONV_CAT(ANGLE)
519     DECLARE_CONV_CAT(AREA)
520     DECLARE_CONV_CAT(CONSUMPTION)
521     DECLARE_CONV_CAT(CURRENCY)
522     DECLARE_CONV_CAT(ENERGY)
523     DECLARE_CONV_CAT(LENGTH)
524     DECLARE_CONV_CAT(POWER)
525     DECLARE_CONV_CAT(PRESSURE)
526     DECLARE_CONV_CAT(TIME)
527     DECLARE_CONV_CAT(TEMPERATURE)
528     DECLARE_CONV_CAT(VELOCITY)
529     DECLARE_CONV_CAT(VOLUME)
530     DECLARE_CONV_CAT(WEIGHT)
531 };
532 
533 void ConvExecute(HWND hWnd)
534 {
535     DWORD         c_cat = (DWORD)SendDlgItemMessage(hWnd, IDC_COMBO_CATEGORY, CB_GETCURSEL, 0, 0);
536     const conv_t *items = NULL;
537     DWORD         from  = SendDlgItemMessage(hWnd, IDC_COMBO_FROM, CB_GETCURSEL, 0, 0);
538     DWORD         to    = SendDlgItemMessage(hWnd, IDC_COMBO_TO,   CB_GETCURSEL, 0, 0);
539     TCHAR         txt_cb[128];
540     TCHAR         txt[128];
541     const conv_t *item;
542 
543     /* do nothing if the indexes point to the same unit */
544     if (from == to)
545         return;
546 
547     /* Search correct category, since it can be sorted too */
548     SendDlgItemMessage(hWnd, IDC_COMBO_CATEGORY, CB_GETLBTEXT, c_cat, (LPARAM)txt_cb);
549     for (c_cat=0; c_cat < SIZEOF(conv_table); c_cat++) {
550         LoadString(calc.hInstance, conv_table[c_cat].category, txt, SIZEOF(txt));
551         if (!_tcscmp(txt_cb, txt)) {
552             items = conv_table[c_cat].items;
553             break;
554         }
555     }
556 
557     /* The units can be sorted, so I must search the exact match */
558     item = items;
559     SendDlgItemMessage(hWnd, IDC_COMBO_FROM, CB_GETLBTEXT, from, (LPARAM)txt_cb);
560     while (item->unit) {
561         LoadString(calc.hInstance, item->unit, txt, SIZEOF(txt));
562         if (!_tcscmp(txt_cb, txt)) {
563             from = item-items;
564             break;
565         }
566         item++;
567     }
568     SendDlgItemMessage(hWnd, IDC_COMBO_TO, CB_GETLBTEXT, to, (LPARAM)txt_cb);
569     item = items;
570     while (item->unit) {
571         LoadString(calc.hInstance, item->unit, txt, SIZEOF(txt));
572         if (!_tcscmp(txt_cb, txt)) {
573             to = item-items;
574             break;
575         }
576         item++;
577     }
578 
579     calc.Convert[0].data = (char *)items[from].formula_from;
580     calc.Convert[1].data = (char *)items[to].formula_to;
581     calc.Convert[0].wm_msg = WM_HANDLE_FROM;
582     calc.Convert[1].wm_msg = WM_HANDLE_TO;
583     PostMessage(hWnd, WM_START_CONV, 0, MAKELPARAM(0, WM_HANDLE_FROM));
584 }
585 
586 void ConvAdjust(HWND hWnd, int n_cat)
587 {
588     TCHAR         txt[128];
589     TCHAR         txt_cat[128];
590     HWND          hFromWnd = GetDlgItem(hWnd, IDC_COMBO_FROM);
591     HWND          hToWnd   = GetDlgItem(hWnd, IDC_COMBO_TO);
592     const conv_t *item;
593     unsigned int  n;
594 
595     SendDlgItemMessage(hWnd, IDC_COMBO_CATEGORY, CB_GETLBTEXT, n_cat, (LPARAM)txt_cat);
596     for (n=0; n<SIZEOF(conv_table); n++) {
597         item = conv_table[n].items;
598         LoadString(calc.hInstance, conv_table[n].category, txt, SIZEOF(txt));
599         if (!_tcscmp(txt_cat, txt))
600             break;
601     }
602 
603     SendMessage(hFromWnd, CB_RESETCONTENT, 0, 0);
604     SendMessage(hToWnd,   CB_RESETCONTENT, 0, 0);
605     while (item->unit) {
606         LoadString(calc.hInstance, item->unit, txt, SIZEOF(txt));
607         SendMessage(hFromWnd, CB_ADDSTRING, 0, (LPARAM)txt);
608         SendMessage(hToWnd,   CB_ADDSTRING, 0, (LPARAM)txt);
609         item++;
610     }
611     SendMessage(hFromWnd, CB_SETCURSEL, 0, 0);
612     SendMessage(hToWnd,   CB_SETCURSEL, 0, 0);
613 }
614 
615 void ConvInit(HWND hWnd)
616 {
617     HWND         hCatWnd = GetDlgItem(hWnd, IDC_COMBO_CATEGORY);
618     TCHAR        txt[128];
619     unsigned int n;
620 
621     /* Fill category combo */
622     for (n=0; n<SIZEOF(conv_table); n++) {
623         LoadString(calc.hInstance, conv_table[n].category, txt, SIZEOF(txt));
624         SendMessage(hCatWnd, CB_ADDSTRING, 0, (LPARAM)txt);
625     }
626     SendMessage(hCatWnd, CB_SETCURSEL, 0, 0);
627     ConvAdjust(hWnd, 0);
628 }
629 
630