windows.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:35k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * windows.cxx
  3.  *
  4.  * Resource compiler MS-Windows resource binary file generator
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: windows.cxx,v $
  30.  * Revision 1.36  2000/06/21 03:15:24  robertj
  31.  * Added ability to append resources to existing file.
  32.  *
  33.  * Revision 1.35  1999/07/27 09:48:13  robertj
  34.  * Removed warning.
  35.  *
  36.  * Revision 1.34  1998/12/23 01:16:15  robertj
  37.  * New directory structure
  38.  *
  39.  * Revision 1.33  1998/09/26 01:24:23  robertj
  40.  * Added open source license
  41.  *
  42.  * Revision 1.32  1998/09/26 01:00:35  robertj
  43.  * Fixed X Windows name conflict.
  44.  *
  45.  * Revision 1.31  1998/09/14 13:54:56  robertj
  46.  * Fixed ansi to unicode conversion in resource output.
  47.  * Added tab stops to list boxes.
  48.  * Fixed group boxes (PStaticBox) so is clipped to specified size allowing single lines.
  49.  *
  50.  * Revision 1.30  1996/01/23 13:26:35  robertj
  51.  * Changed resource ID mechanism.
  52.  *
  53.  * Revision 1.29  1996/01/02 13:06:02  robertj
  54.  * Changes to support editor.
  55.  *
  56.  * Revision 1.28  1995/12/23 03:53:03  robertj
  57.  * Removed multiple classes for layout types.
  58.  *
  59.  * Revision 1.27  1995/12/10 12:12:10  robertj
  60.  * Changes to support graphical resource file editor.
  61.  *
  62.  * Revision 1.26  1995/08/24 12:52:49  robertj
  63.  * Added general control type for arbitrary dialog controls.
  64.  * Added output file extension variable.
  65.  *
  66.  * Revision 1.25  1995/07/02 06:24:24  robertj
  67.  * Fixed bug with menu accelerators resource in WIN32.
  68.  *
  69.  * Revision 1.24  1995/04/22 01:04:29  robertj
  70.  * Fixed styles for controls in WIN16.
  71.  *
  72.  * Revision 1.23  1995/04/02 09:28:18  robertj
  73.  * Added "balloon" help.
  74.  *
  75.  * Revision 1.22  1995/03/22 13:58:25  robertj
  76.  * Fixed bug in colour table in resource images, icons etc.
  77.  *
  78.  * Revision 1.21  1995/02/11  04:15:14  robertj
  79.  * Strange problem with variable "small" in MSVC 2.0.
  80.  *
  81.  * Revision 1.20  1995/01/27  11:25:54  robertj
  82.  * Added pattern resource.
  83.  *
  84.  * Revision 1.19  1995/01/11  09:45:22  robertj
  85.  * Documentation and normalisation.
  86.  *
  87.  * Revision 1.18  1994/12/12  13:14:08  robertj
  88.  * Changed RealEdit to FloatEdit.
  89.  *
  90.  * Revision 1.17  1994/10/30  11:30:39  robertj
  91.  * Fixed standard get directory dialog resource.
  92.  *
  93.  * Revision 1.16  1994/10/23  06:09:03  robertj
  94.  * Changed TextEditor so return does not close dialogs.
  95.  *
  96.  * Revision 1.15  1994/08/22  00:23:54  robertj
  97.  * Fixed bug in standard get directory dialog.
  98.  *
  99.  * Revision 1.14  1994/07/02  03:25:39  robertj
  100.  * Fixed bug.
  101.  *
  102.  * Revision 1.13  1994/06/25  12:16:28  robertj
  103.  * Synchonsiation with unix implementation.
  104.  *
  105.  * Revision 1.12  1994/04/03  08:37:00  robertj
  106.  * *** empty log message ***
  107.  *
  108.  * Revision 1.11  1994/04/01  14:29:16  robertj
  109.  * New format PRC file
  110.  *
  111.  * Revision 1.10  1994/01/03  04:34:30  robertj
  112.  * Changed scan lines in internal structure to top to bottom.
  113.  *
  114.  * Revision 1.9  1993/12/31  07:05:07  robertj
  115.  * Changed pixmap images for one pixel one number in PRC file.
  116.  *
  117.  * Revision 1.8  1993/12/14  18:54:42  robertj
  118.  * WIN32 port.
  119.  *
  120.  * Revision 1.7  1993/08/20  21:31:56  robertj
  121.  * Fixed bug in extra byte in bitmap image raster data.
  122.  *
  123.  * Revision 1.7  1993/08/10  13:08:09  robertj
  124.  * Fixed bug with extra byte in bitmap image scan lines.
  125.  *
  126.  * Revision 1.6  1993/07/17  02:57:00  robertj
  127.  * Further implementation
  128.  *
  129.  * Revision 1.5  1993/07/16  14:48:43  robertj
  130.  * Fixed header comment.
  131.  * Fixed DWORD padding on scan lines in bitmaps.
  132.  *
  133.  * Revision 1.4  1993/07/16  12:53:12  robertj
  134.  * Added converted form of C literal string to resource objects.
  135.  * Changed DIALOGSTRINGS resource format to be more usefull.
  136.  *
  137.  * Revision 1.3  1993/07/15  04:38:31  robertj
  138.  * Rationalised lex.h, parse.h and main.h out of existance.
  139.  *
  140.  * Revision 1.2  1993/07/14  01:57:48  robertj
  141.  * Fixed bug in not getting long alignment in bitmaps.
  142.  *
  143.  * Revision 1.1  1993/07/03  06:00:47  robertj
  144.  * Initial revision
  145.  *
  146.  */
  147. #include <ptlib.h>
  148. #ifndef WIN32
  149. #undef NEAR
  150. #endif
  151. #include <windows.h>
  152. #include <fcntl.h>
  153. #include "pwrc.h"
  154. #include "pwlib/stdresid.h"
  155. #define DIALOGSTRINGS "DIALOGSTRINGS"
  156. PString OutputExtension(".res");
  157. PString CxxExtension(".cxx");
  158. static enum { OutputMenus, CountAccelerators, OutputAccelerators } MenuPass;
  159. static int HasAccelerators;
  160. static BYTE LastAcceleratorFlags;
  161. static BOOL LastMenu;
  162. static BOOL OutputDialogStrings;
  163. static BYTE DialogControlCode;
  164. static DWORD DialogControlStyle;
  165. static enum {
  166.   BilevelIcon,
  167.   BilevelCursor,
  168.   ColourIcon,
  169.   ColourCursor,
  170.   PixmapImage,
  171.   IconDirMap,
  172.   CursorDirMap
  173. } OutputIconCursor;
  174. static WORD IconCursorID;
  175. static int PixDataWidth;
  176. static int PixDataDepth;
  177. //////////////////////////////////////////////////////////////////////////////
  178. // Support classes for binary stream output
  179. class BinByte {
  180.   public:
  181.     inline BinByte(int nb)
  182.       : b((char)nb) { }
  183.     inline friend ostream & operator<<(ostream & out, const BinByte & b)
  184.       { out.put(b.b); return out; }
  185.   protected:
  186.     char b;
  187. };
  188. class BinWord {
  189.   public:
  190.     inline BinWord(int nw)
  191.       : w((short)nw) { }
  192.     inline friend ostream & operator<<(ostream & out, const BinWord & w)
  193.       { out.write((char *)&w.w, sizeof(w.w)); return out; }
  194.   protected:
  195.     short w;
  196. };
  197. #ifdef WIN32
  198. #define BinTextChar BinWord
  199. #else
  200. #define BinTextChar BinByte
  201. #endif
  202. class BinLong {
  203.   public:
  204.     inline BinLong(long nl)
  205.       : l(nl) { }
  206.     inline friend ostream & operator<<(ostream & out, const BinLong & l)
  207.       { out.write((char *)&l.l, sizeof(l.l)); return out; }
  208.   protected:
  209.     long l;
  210. };
  211. class BinStr {
  212.   public:
  213.     inline BinStr(const PString & str)
  214.       : s(str) { }
  215.     friend ostream & operator<<(ostream & out, const BinStr & s);
  216.   protected:
  217.     PString s;
  218. };
  219. static int ConvertAnsiToUnicode(const PString & s, PWORDArray & unicode)
  220. {
  221.   int len = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, s, s.GetLength(), NULL, 0);
  222.   MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, s, -1, unicode.GetPointer(len), len);
  223.   return len;
  224. }
  225. ostream & operator<<(ostream & out, const BinStr & s)
  226. {
  227. #ifdef WIN32
  228.   PWORDArray wide;
  229.   int len = ConvertAnsiToUnicode(s.s, wide);
  230.   for (int i = 0; i < len; i++)
  231.     out << BinWord(wide[i]);
  232.   return out << BinWord(0);
  233. #else
  234.   return out << s.s << BinByte(0);
  235. #endif
  236. }
  237. class ResHdr {
  238.   public:
  239.     inline ResHdr(int rType, int rId)
  240.       : type((short)rType), id((short)rId), lenpos(-1) { }
  241.     inline ResHdr(const PString & rType, int rId)
  242.       : sType(rType), id((short)rId), lenpos(-1) { }
  243.     inline void SetType(int rType)
  244.       { type = (short)rType; }
  245.     inline void SetType(const PString & rType)
  246.       { sType = rType; }
  247.     friend ostream & operator<<(ostream & out, ResHdr & h);
  248.   protected:
  249.     short type, id;
  250.     PString sType;
  251.     streampos lenpos;
  252.     streampos endhdrpos;
  253. };
  254. ostream & operator<<(ostream & out, ResHdr & h)
  255. {
  256.   if (h.lenpos != -1) {
  257.     BinLong len = out.tellp() - h.endhdrpos;
  258.     out.seekp(h.lenpos);
  259.     out << len;
  260. #ifdef WIN32
  261.     out << BinLong(h.endhdrpos - h.lenpos);
  262. #endif
  263.     out.seekp(0, ios::end);
  264.   }
  265.   else {
  266. #ifdef WIN32
  267.     while (((h.lenpos = out.tellp())&3) != 0) // Align to long
  268.       out.put('');
  269.     out << BinLong(0) << BinLong(0);
  270.     if (h.sType.IsEmpty())
  271.       out << BinWord(0xffff) << BinWord(h.type);
  272.     else
  273.       out << BinStr(h.sType);
  274.     out << BinWord(0xffff) << BinWord(h.id);
  275.     while ((out.tellp()&3) != 0) // Align to long
  276.       out.put('');
  277.     out << BinLong(0) << BinLong(0x04091030) << BinLong(0) << BinLong(0);
  278. #else
  279.     if (h.sType.IsEmpty())
  280.       out << BinByte(0xffff) << BinWord(h.type);
  281.     else
  282.       out << h.sType << BinByte(0);
  283.     out << BinByte(0xff) << BinWord(h.id) << BinWord(0x1030);
  284.     h.lenpos = out.tellp();
  285.     out << BinLong(0);
  286. #endif
  287.     h.endhdrpos = out.tellp();
  288.   }
  289.   return out;
  290. }
  291. ///////////////////////////////////////////////////////////////
  292. //
  293. //  StringDict::PrintOn
  294. //
  295. void StringDict::PrintOn(ostream & out) const
  296. {
  297.   char set[4096/8];
  298.   memset(set, 0, sizeof(set));
  299.   for (int i = 0; i < GetSize(); i++) {
  300.     unsigned id = (unsigned)GetKeyAt(i) >> 4;
  301.     set[id>>3] |= 1 << (id&7);
  302.   }
  303.   for (i = 0; i < 4096; i++) {
  304.     if ((set[i>>3]&(1<<(i&7))) != 0) {
  305.       ResHdr hdr(6, i+1);
  306.       out << hdr;
  307.       for (int j = 0; j < 16; j++) {
  308.         ResourceObject * res;
  309.         if ((res = (ResourceObject *)GetAt(i*16+j)) == NULL)
  310.           out << BinTextChar(0);
  311.         else {
  312. #ifdef WIN32
  313.           PWORDArray wide;
  314.           int len = ConvertAnsiToUnicode(res->GetConvertedText(), wide);
  315.           out << BinWord(len);
  316.           for (int k = 0; k < len; k++)
  317.             out << BinWord(wide[k]);
  318. #else
  319.           out << BinByte(res->GetConvertedText().GetLength()) << res->GetConvertedText();
  320. #endif
  321.         }
  322.       }
  323.       out << hdr;
  324.     }
  325.   }
  326. }
  327. ///////////////////////////////////////////////////////////////
  328. //
  329. //  MenuItem::PrintOn
  330. //
  331. void MenuItem::PrintOn(ostream & out) const
  332. {
  333.   switch (MenuPass) {
  334.     case OutputMenus :
  335.       out << BinWord(LastMenu ? (WORD)MF_END : 0) << BinWord(id);
  336.       if (accel.IsEmpty() || accel[0].GetValue() < PKeyCode::A ||
  337.                              accel[0].GetValue() > PKeyCode::Space)
  338.         out << BinStr(textConverted);
  339.       else {
  340.         static char *ValueStrings[] = {
  341.           NULL, NULL, NULL, NULL,
  342.           "A","B","C","D","E","F","G","H","I","J","K","L","M",
  343.           "N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
  344.           "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
  345.           "NumPad0", "NumPad1", "NumPad2", "NumPad3", "NumPad4",
  346.           "NumPad5", "NumPad6", "NumPad7", "NumPad8", "NumPad9",
  347.           "NumPad+", "NumPad-", "NumPad*", "NumPad/", "NumPad,", "NumPad.",
  348.           "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10","F11","F12",
  349.           "F13","F14","F15","F16","F17","F18","F19","F20","F21","F22","F23","F24",
  350.           "Up", "Down", "Left", "Right", "PgUp", "PgDn", "Home", "End",
  351.           "Ins", "Del", "Undo", "Cut", "Copy", "Paste", "Clear", "Cancel", "Help", "Quit",
  352.           "BkSp", "Tab", "Enter", "Esc", "Space"
  353.         };
  354.         static int ModifierOrder[] = {
  355.           PKeyCode::Option,
  356.           PKeyCode::Command,
  357.           PKeyCode::Alt,
  358.           PKeyCode::Shift,
  359.           PKeyCode::Control,
  360.           PKeyCode::CapsLock,
  361.           PKeyCode::Accelerator1,
  362.           PKeyCode::Accelerator2,
  363.           0
  364.         };
  365.         PString modifers;
  366.         for (int i = 0; ModifierOrder[i] != 0; i++) {
  367.           if (accel[0].IsModifier(ModifierOrder[i])) {
  368.             switch (accel[0].GetModifiers() & ModifierOrder[i]) {
  369.               case PKeyCode::Shift:
  370.                 modifers += "Shift+";
  371.                 break;
  372.               case PKeyCode::Command:
  373.               case PKeyCode::Control:
  374.               case PKeyCode::Accelerator1:
  375.                 modifers += "Ctrl+";
  376.                 break;
  377.               case PKeyCode::Alt:
  378.                 modifers += "Alt+";
  379.                 break;
  380.               case PKeyCode::Option:
  381.                 modifers += "Opt";
  382.                 break;
  383.               case PKeyCode::Accelerator2:
  384.                 modifers += "Ctrl+Shift+";
  385.             }
  386.           }
  387.         }
  388.         out << BinStr(textConverted +
  389.                           "t" + modifers + ValueStrings[accel[0].GetValue()]);
  390.       }
  391.       break;
  392.     case CountAccelerators :
  393.       if (!accel.IsEmpty())
  394.         HasAccelerators = TRUE;
  395.       break;
  396.     case OutputAccelerators :
  397.       for (PINDEX i = 0; i < accel.GetSize(); i++) {
  398.         static WORD toVK[] = { 
  399.           0, VK_LBUTTON, VK_RBUTTON, VK_MBUTTON,
  400.           'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  401.           'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  402.           '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  403.           VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
  404.           VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9,
  405.           VK_ADD, VK_SUBTRACT, VK_MULTIPLY, VK_DIVIDE, VK_SEPARATOR, VK_DECIMAL,    
  406.           VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8,
  407.           VK_F9, VK_F10, VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16,
  408.           VK_F17, VK_F18, VK_F19, VK_F20, VK_F21, VK_F22, VK_F23, VK_F24, 
  409.           VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_HOME, VK_END,
  410.           VK_INSERT, VK_DELETE, VK_F20, VK_F21, VK_F22, VK_F23,
  411.           VK_CLEAR, VK_CANCEL, VK_HELP, VK_F24,
  412.           VK_BACK, VK_TAB, VK_RETURN, VK_ESCAPE, VK_SPACE,
  413.           VK_CAPITAL, VK_SHIFT, VK_CONTROL, VK_MENU, VK_CONTROL, VK_MENU, VK_MENU,
  414.           VK_PAUSE, VK_SELECT, 0x2a, VK_EXECUTE, VK_SNAPSHOT, VK_NUMLOCK, VK_SCROLL,
  415.           0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  416.           0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe6, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
  417.           0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5
  418.         };
  419.         BYTE flags = 1;
  420.         if (accel[i].IsModifier(PKeyCode::Shift))
  421.           flags |= 0x04;
  422.         if (accel[i].IsModifier(PKeyCode::Control|PKeyCode::Command|PKeyCode::Accelerator1))
  423.           flags |= 0x08;
  424.         if (accel[i].IsModifier(PKeyCode::Alt|PKeyCode::Option))
  425.           flags |= 0x10;
  426.         if (accel[i].IsModifier(PKeyCode::Accelerator2))
  427.           flags |= 0x0c;
  428.         LastAcceleratorFlags = flags;
  429.         out << BinTextChar(flags)
  430.             << BinWord(toVK[accel[i].GetValue()])
  431.             << BinWord(id);
  432. #ifdef WIN32
  433.         out << BinWord(0);
  434. #endif
  435.       }
  436.   }
  437. }
  438. ///////////////////////////////////////////////////////////////
  439. //
  440. //  Separator::PrintOn
  441. //
  442. void Separator::PrintOn(ostream & out) const
  443. {
  444.   if (MenuPass == OutputMenus)
  445.     out << BinWord((WORD)(MF_SEPARATOR|(LastMenu ? MF_END : 0)))
  446.         << BinWord(0) << BinTextChar(0);
  447. }
  448. ///////////////////////////////////////////////////////////////
  449. //
  450. //  Menu::PrintOn
  451. //
  452. void Menu::PrintOn(ostream & out) const
  453. {
  454.   if (MenuPass == OutputMenus)
  455.     out << BinWord((WORD)(MF_POPUP|(LastMenu ? MF_END : 0)))
  456.         << BinStr(textConverted);
  457.   // output items
  458.   for (int i = 0; i < items.GetSize(); i++) {
  459.     LastMenu = i == items.GetSize()-1;
  460.     out << items[i];
  461.   }
  462. }
  463. ///////////////////////////////////////////////////////////////
  464. //
  465. //  Menubar::PrintOn
  466. //
  467. void MenuBar::PrintOn(ostream & out) const
  468. {
  469.   ResHdr hdr(4, id);
  470.   switch (MenuPass) {
  471.     case OutputMenus :
  472.       out << hdr << BinWord(0) << BinWord(0);
  473.       break;
  474.     case OutputAccelerators :
  475.       hdr.SetType(9);
  476.       out << hdr;
  477.       break;
  478.   }
  479.   
  480.   // output data for menubar
  481.   for (int i = 0; i < menus.GetSize(); i++) {
  482.     LastMenu = i == menus.GetSize()-1;
  483.     out << menus[i];
  484.   }
  485.   if (MenuPass != CountAccelerators)
  486.     out << hdr;
  487. }
  488. ///////////////////////////////////////////////////////////////
  489. //
  490. //  MenubarDict::PrintOn
  491. //
  492. void MenubarDict::PrintOn(ostream & out) const
  493. {
  494.   //  output each of the menubars
  495.   for (int i = 0; i < GetSize(); i++) {
  496.     MenuPass = OutputMenus;
  497.     out << GetDataAt(i);
  498.     MenuPass = CountAccelerators;
  499.     HasAccelerators = FALSE;
  500.     out << GetDataAt(i);
  501.     if (HasAccelerators) {
  502.       MenuPass = OutputAccelerators;
  503.       out << GetDataAt(i);
  504. #ifdef WIN32
  505.       out.seekp(-8, ios::cur);
  506. #else
  507.       out.seekp(-5, ios::cur);
  508. #endif
  509.       out << BinByte(LastAcceleratorFlags|0x80);
  510.       out.seekp(0, ios::end);
  511.     }
  512.   }
  513. }
  514. ///////////////////////////////////////////////////////////////
  515. //
  516. //  output routines for various control types
  517. //
  518. void Point::PrintOn(ostream & out) const
  519. {
  520.   out << BinWord(x) << BinWord(y);
  521. }
  522. void Control::PrintOn(ostream & out) const
  523. {
  524.   if (OutputDialogStrings) {
  525.     out << BinStr(PString(PString::Literal, balloonHelp));
  526.     return;
  527.   }
  528. #ifdef WIN32
  529.   while ((out.tellp()&3) != 0) // Align to long
  530.     out.put('');
  531.   out << BinLong(DialogControlStyle|WS_VISIBLE|WS_CHILD) << BinLong(0)
  532.       << pos << dim << BinWord(id) << BinWord(0xffff)
  533. #else
  534.   out << pos << dim << BinWord(id)
  535.       << BinLong(DialogControlStyle|WS_VISIBLE|WS_CHILD)
  536. #endif
  537.       << BinTextChar(DialogControlCode);
  538.   if (iconID == -1)
  539.     out << BinStr(textConverted) << BinTextChar(0);
  540. }
  541. void PushButton::PrintOn(ostream & out) const
  542. {
  543.   DialogControlCode = 0x80;
  544.   DialogControlStyle = (options&DefaultButtonOption) != 0 ? BS_DEFPUSHBUTTON
  545.                                                    : BS_PUSHBUTTON;
  546.   DialogControlStyle |= WS_TABSTOP;
  547.   Control::PrintOn(out);
  548. }
  549. void CheckBox::PrintOn(ostream & out) const
  550. {
  551.   DialogControlCode = 0x80;
  552.   DialogControlStyle = BS_AUTOCHECKBOX|WS_TABSTOP;
  553.   Control::PrintOn(out);
  554. }
  555. void Check3Way::PrintOn(ostream & out) const
  556. {
  557.   DialogControlCode = 0x80;
  558.   DialogControlStyle = BS_AUTO3STATE|WS_TABSTOP;
  559.   Control::PrintOn(out);
  560. }
  561. void RadioButton::PrintOn(ostream & out) const
  562. {
  563.   DialogControlCode = 0x80;
  564.   DialogControlStyle = BS_RADIOBUTTON|WS_TABSTOP;
  565.   Control::PrintOn(out);
  566. }
  567. void LeftText::PrintOn(ostream & out) const
  568. {
  569.   DialogControlCode = 0x82;
  570.   DialogControlStyle = SS_LEFT;
  571.   Control::PrintOn(out);
  572. }
  573. void CentreText::PrintOn(ostream & out) const
  574. {
  575.   DialogControlCode = 0x82;
  576.   DialogControlStyle = SS_CENTER;
  577.   Control::PrintOn(out);
  578. }
  579. void RightText::PrintOn(ostream & out) const
  580. {
  581.   DialogControlCode = 0x82;
  582.   DialogControlStyle = SS_RIGHT;
  583.   Control::PrintOn(out);
  584. }
  585. void StaticBox::PrintOn(ostream & out) const
  586. {
  587.   DialogControlCode = 0x80;
  588.   DialogControlStyle = BS_GROUPBOX|WS_CLIPSIBLINGS;
  589.   Control::PrintOn(out);
  590. }
  591. void EditBox::PrintOn(ostream & out) const
  592. {
  593.   DialogControlCode = 0x81;
  594.   DialogControlStyle = ES_LEFT|ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP;
  595.   Control::PrintOn(out);
  596. }
  597. void IntEditBox::PrintOn(ostream & out) const
  598. {
  599.   DialogControlCode = 0x81;
  600.   DialogControlStyle = ES_LEFT|WS_BORDER|WS_TABSTOP;
  601.   ((IntEditBox*)this)->textConverted = psprintf("INTEDITBOX %li %li %li %li",
  602.                                      minimum, maximum, smallNudge, largeNudge);
  603.   Control::PrintOn(out);
  604. }
  605. void FloatEditBox::PrintOn(ostream & out) const
  606. {
  607.   DialogControlCode = 0x81;
  608.   DialogControlStyle = ES_LEFT|WS_BORDER|WS_TABSTOP;
  609.   ((FloatEditBox*)this)->textConverted =
  610.                             psprintf("FLOATEDITBOX %li %li %li %li",
  611.                                      minimum, maximum, smallNudge, largeNudge);
  612.   Control::PrintOn(out);
  613. }
  614. void TextEditor::PrintOn(ostream & out) const
  615. {
  616.   DialogControlCode = 0x81;
  617.   DialogControlStyle = ES_LEFT|ES_MULTILINE|ES_WANTRETURN|
  618.                                     WS_VSCROLL|WS_HSCROLL|WS_BORDER|WS_TABSTOP;
  619.   Control::PrintOn(out);
  620. }
  621. void Password::PrintOn(ostream & out) const
  622. {
  623.   DialogControlCode = 0x81;
  624.   DialogControlStyle = ES_LEFT|ES_PASSWORD|WS_BORDER|WS_TABSTOP;
  625.   Control::PrintOn(out);
  626. }
  627. void ListControl::PrintOn(ostream & out) const
  628. {
  629.   Control::PrintOn(out);
  630.   if (OutputDialogStrings)
  631.     for (PINDEX i = 0; i < strList.GetSize(); i++)
  632.       out << BinStr(PString(PString::Literal, strList[i]));
  633. }
  634. void ChoiceBox::PrintOn(ostream & out) const
  635. {
  636.   DialogControlCode = 0x85;
  637.   DialogControlStyle = CBS_DROPDOWNLIST|WS_VSCROLL|WS_BORDER|WS_TABSTOP;
  638.   if ((options&Special) != 0)
  639.     DialogControlStyle |= CBS_SORT|CBS_OWNERDRAWFIXED|CBS_HASSTRINGS;
  640.   else if ((options&SortedOption) != 0)
  641.     DialogControlStyle |= CBS_SORT;
  642.   ListControl::PrintOn(out);
  643. }
  644. void ListBox::PrintOn(ostream & out) const
  645. {
  646.   DialogControlCode = 0x83;
  647.   DialogControlStyle = LBS_USETABSTOPS|LBS_NOINTEGRALHEIGHT|LBS_NOTIFY|WS_BORDER|WS_TABSTOP;
  648.   if ((options&Special) != 0)
  649.     DialogControlStyle |= WS_VSCROLL|LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|LBS_SORT;
  650.   else {
  651.     if ((options&SortedOption) != 0)
  652.       DialogControlStyle |= LBS_SORT;
  653.     if ((options&MultiSelectOption) != 0)
  654.       DialogControlStyle |= LBS_EXTENDEDSEL;
  655.     if ((options&MultiColumnOption) != 0)
  656.       DialogControlStyle |= LBS_MULTICOLUMN|WS_HSCROLL;
  657.     else
  658.       DialogControlStyle |= LBS_DISABLENOSCROLL|WS_VSCROLL;
  659.     if (GetResClass() != "PStringListBox")
  660.       DialogControlStyle |= (options&MultiColumnOption) != 0
  661.                                 ? LBS_OWNERDRAWFIXED : LBS_OWNERDRAWVARIABLE;
  662.   }
  663.   ListControl::PrintOn(out);
  664. }
  665. void ComboBox::PrintOn(ostream & out) const
  666. {
  667.   DialogControlCode = 0x85;
  668.   DialogControlStyle =
  669.                 CBS_AUTOHSCROLL|CBS_DROPDOWN|WS_VSCROLL|WS_BORDER|WS_TABSTOP;
  670.   if ((options&SortedOption) != 0)
  671.     DialogControlStyle |= CBS_SORT;
  672.   if ((options&Special) != 0)
  673.     DialogControlStyle |= CBS_OWNERDRAWFIXED|CBS_HASSTRINGS;
  674.   ListControl::PrintOn(out);
  675. }
  676. void HScrollBar::PrintOn(ostream & out) const
  677. {
  678.   DialogControlCode = 0x84;
  679.   DialogControlStyle = SBS_HORZ|WS_TABSTOP;
  680.   ((HScrollBar*)this)->textConverted = psprintf("%li %li %li %li",
  681.                                      minimum, maximum, smallNudge, largeNudge);
  682.   Control::PrintOn(out);
  683. }
  684. void VScrollBar::PrintOn(ostream & out) const
  685. {
  686.   DialogControlCode = 0x84;
  687.   DialogControlStyle = SBS_VERT|WS_TABSTOP;
  688.   ((VScrollBar*)this)->textConverted = psprintf("%li %li %li %li",
  689.                                      minimum, maximum, smallNudge, largeNudge);
  690.   Control::PrintOn(out);
  691. }
  692. void StaticIcon::PrintOn(ostream & out) const
  693. {
  694.   DialogControlCode = 0x82;
  695.   DialogControlStyle = SS_ICON;
  696.   Control::PrintOn(out);
  697.   if (!OutputDialogStrings)
  698.     out << BinTextChar(0xffff) << BinWord(iconID) << BinTextChar(0);
  699. }
  700. void UserControl::PrintOn(ostream & out) const 
  701.   DialogControlCode = 0x82;
  702.   DialogControlStyle = SS_LEFT;
  703.   Control::PrintOn(out);
  704. ///////////////////////////////////////////////////////////////
  705. //
  706. //  Layout::PrintOn
  707. //
  708. void Layout::PrintOn(ostream & out) const
  709. {
  710.   ResHdr hdr(5, id);
  711.   
  712.   if (OutputDialogStrings) {
  713.     hdr.SetType(DIALOGSTRINGS);
  714.     out << hdr;
  715.   }
  716.   else {
  717.     DWORD style = WS_CLIPCHILDREN|WS_CLIPSIBLINGS|DS_SETFONT;
  718.     if (subtype == 0)
  719.       style |= WS_CHILD;
  720.     else
  721.       style |= WS_POPUP|WS_CAPTION|WS_SYSMENU|DS_MODALFRAME;
  722.     out << hdr
  723.         << BinLong(style)          // Window style
  724. #ifdef WIN32
  725.         << BinLong(0)  // Window extended style
  726. #endif
  727.         << BinTextChar(itemList.GetSize()) // number of items
  728.         << BinWord(pos.X())
  729.         << BinWord(pos.Y())
  730.         << BinWord(dim.X())
  731.         << BinWord(dim.Y())
  732.         << BinTextChar(0)     // Menu name (no menu)
  733.         << BinTextChar(0)     // Class name (default class)
  734.         << BinStr(textConverted);  // caption
  735.     if (fontName.IsEmpty())
  736.       out << BinWord(8) << BinStr("MS Sans Serif");
  737.     else
  738.       out << BinWord(fontSize)
  739.           << BinStr(PString(PString::Literal, fontName));
  740.   }
  741.   for (int i = 0; i < itemList.GetSize(); i++) {
  742.     out << itemList[i];
  743.     if (OutputDialogStrings)
  744.       out << BinTextChar(0); // Terminator
  745.   }
  746.   out << hdr;
  747. }
  748. ///////////////////////////////////////////////////////////////
  749. //
  750. //  DialogDict::PrintOn
  751. //
  752. void DialogDict::PrintOn(ostream & out) const
  753. {
  754.   //  output each of the dialogs
  755.   for (int i = 0; i < GetSize(); i++) {
  756.     OutputDialogStrings = FALSE;
  757.     out << GetDataAt (i);
  758.     OutputDialogStrings = TRUE;
  759.     out << GetDataAt (i);
  760.   }
  761. }
  762. ///////////////////////////////////////////////////////////////
  763. //
  764. //  BinaryData::PrintOn
  765. //
  766. void BinaryData::PrintOn(ostream & out) const
  767. {
  768.   out.write(theArray, GetSize());
  769. }
  770. ///////////////////////////////////////////////////////////////
  771. //
  772. //  PixData::PrintOn
  773. //
  774. void PixData::PrintOn(ostream & out) const
  775. {
  776.   if (PixDataDepth > 8) {
  777.     for (int y = GetSize()/PixDataWidth/3-1; y >= 0; y--) {
  778.       const char * pixels = theArray+y*PixDataWidth*3;
  779.       for (PINDEX x = 0; x < PixDataWidth*3; x++)
  780.         out << *pixels++ << ' ';
  781.       while ((x++&3) != 0) // Align to long
  782.         out.put('');
  783.     }
  784.   }
  785.   else {
  786.     for (int y = GetSize()/PixDataWidth-1; y >= 0; y--) {
  787.       const char * pixels = theArray+y*PixDataWidth;
  788.       PINDEX byteCount = 0;
  789.       PINDEX pixelsPerByte = 8/PixDataDepth;
  790.       PINDEX pixelInByte = 0;
  791.       char byte = 0;
  792.       for (PINDEX pix = 0; pix < PixDataWidth; pix++) {
  793.         byte <<= PixDataDepth;
  794.         byte |= *pixels++;
  795.         if (++pixelInByte >= pixelsPerByte) {
  796.           out.put(byte);
  797.           byteCount++;
  798.           pixelInByte = 0;
  799.           byte = 0;
  800.         }
  801.       }
  802.       if (pixelInByte != 0) {
  803.         out.put((char)(byte << (8-pixelInByte)));
  804.         byteCount++;
  805.       }
  806.       while ((byteCount++&3) != 0) // Align to long
  807.         out.put('');
  808.     }
  809.   }
  810. }
  811. ///////////////////////////////////////////////////////////////
  812. //
  813. //  PixelContents::PrintOn
  814. //
  815. void PixelContents::PrintOn(ostream & out) const
  816. {
  817.   static RGBQUAD bw[2] = { { 0, 0, 0, 0 }, { 255, 255, 255, 0 } };
  818.   PixDataWidth = width;
  819.   BITMAPINFOHEADER bm;
  820.   memset(&bm, 0, sizeof(bm));
  821.   bm.biSize = sizeof(bm);
  822.   bm.biWidth = width;
  823.   bm.biHeight = height;
  824.   bm.biPlanes = 1;
  825.   switch (OutputIconCursor) {
  826.     case BilevelCursor :
  827.       out << BinWord(x) << BinWord(y); // Hotspot
  828.       // Then do common code in BiLevelIcon case
  829.     case BilevelIcon :
  830.       bm.biHeight *= 2;
  831.       bm.biBitCount = 1;
  832.       bm.biSizeImage = ((bm.biWidth+31)/32)*4*bm.biHeight;
  833.       bm.biClrUsed = bm.biClrImportant = 2L;
  834.       out.write((char *)&bm, sizeof(bm));
  835.       out.write((char *)bw, sizeof(bw));
  836.       PixDataDepth = 1;
  837.       out << xorMask << andMask;
  838.       break;
  839.     
  840.     case ColourCursor :
  841.       out << BinWord(x) << BinWord(y); // Hotspot
  842.       // Then do common code in ColourIcon case
  843.     case ColourIcon :
  844.       bm.biHeight *= 2;
  845.       // Then do common code in PixmapImage case
  846.     case PixmapImage :
  847.       bm.biBitCount = (WORD)depth;
  848.       bm.biSizeImage = ((bm.biWidth*bm.biBitCount+31)/32)*4*bm.biHeight;
  849.       bm.biClrUsed = bm.biClrImportant = 1L << bm.biBitCount;
  850.       out.write((char *)&bm, sizeof(bm));
  851.   
  852.       if (depth != 24) {
  853.         for (int i = 0; i < (int)bm.biClrUsed; i++) {
  854.           RGBQUAD rgb;
  855.           rgb.rgbRed = clut[i*3];
  856.           rgb.rgbGreen = clut[i*3+1];
  857.           rgb.rgbBlue = clut[i*3+2];
  858.           rgb.rgbReserved = 0;
  859.           out.write((char *)&rgb, sizeof(rgb));
  860.         }
  861.       }
  862.       PixDataDepth = depth;
  863.       out << pixels;
  864.       PixDataDepth = 1;
  865.       if (andMask.GetSize() > 0)
  866.         out << andMask;
  867.       break;
  868.     case IconDirMap :
  869.       out << BinWord(depth != 1 ? 2 : 1)
  870.           << BinByte(width) << BinByte(height) // First the B/W icon/cursor
  871.           << BinWord(2) // Number of colours
  872.           << BinWord(1) // Bit planes/hotspot x
  873.           << BinWord(1) // Bits per pixel/hotspot y
  874.           << BinLong(sizeof(BITMAPINFOHEADER) +
  875.                                 2*andMask.GetSize() + 2*sizeof(RGBQUAD)) // Size
  876.           << BinWord(IconCursorID++);
  877.   
  878.       if (depth != 1)
  879.         out << BinByte(width) << BinByte(height) // Second the colour icon/cursor
  880.             << BinWord(1 << depth) // Number of colours
  881.             << BinWord(1) // Bit planes/hotspot x
  882.             << BinWord(depth) // Bits per pixel/hotspot y
  883.             << BinLong(sizeof(BITMAPINFOHEADER) +
  884.                        pixels.GetSize() + andMask.GetSize() +
  885.                        (depth != 24 ? ((1<<depth)*sizeof(RGBQUAD)) : 0)) // Size
  886.             << BinWord(IconCursorID++);
  887.       break;
  888.     case CursorDirMap :
  889.       out << BinWord(depth != 1 ? 2 : 1)
  890.           << BinWord(width) << BinWord(height) // First the B/W icon/cursor
  891.           << BinWord(1) // Bit planes
  892.           << BinWord(1) // Bits per pixel
  893.           << BinLong(sizeof(BITMAPINFOHEADER) +
  894.                                 2*andMask.GetSize() + 2*sizeof(RGBQUAD)) // Size
  895.           << BinWord(IconCursorID++);
  896.   
  897.       if (depth != 1)
  898.         out << BinWord(width) << BinWord(height) // Second the colour icon/cursor
  899.             << BinWord(1) // Bit planes
  900.             << BinWord(depth) // Bits per pixel
  901.             << BinLong(sizeof(BITMAPINFOHEADER) +
  902.                        pixels.GetSize() + andMask.GetSize() +
  903.                        (depth != 24 ? ((1<<depth)*sizeof(RGBQUAD)) : 0)) // Size
  904.             << BinWord(IconCursorID++);
  905.   }
  906. }
  907. ///////////////////////////////////////////////////////////////
  908. //
  909. //  Icon::PrintOn
  910. //
  911. void Icon::PrintOn(ostream & out) const
  912. {
  913.   OutputIconCursor = BilevelIcon;
  914.   ResHdr hdr(3, IconCursorID);
  915.   out << hdr << contents << hdr;
  916.   if (contents.depth != 1) {
  917.     OutputIconCursor = ColourIcon;
  918.     ResHdr colhdr(3, IconCursorID+1);
  919.     out << colhdr << contents << colhdr;
  920.   }
  921.   OutputIconCursor = IconDirMap;
  922.   ResHdr dirhdr(14, id);
  923.   out << dirhdr << BinWord(0) << BinWord(1) << contents << dirhdr;
  924. }
  925. ///////////////////////////////////////////////////////////////
  926. //
  927. //  IconDict::PrintOn
  928. //
  929. void IconDict::PrintOn(ostream & out) const
  930. {
  931.   IconCursorID = 1;
  932.   //  output each of the icons
  933.   for (int i = 0; i < GetSize(); i++)
  934.     out << GetDataAt (i);
  935. }
  936. ///////////////////////////////////////////////////////////////
  937. //
  938. //  Cursor::PrintOn
  939. //
  940. void CursorResource::PrintOn(ostream & out) const
  941. {
  942.   OutputIconCursor = BilevelCursor;
  943.   ResHdr hdr(1, IconCursorID);
  944.   out << hdr << contents << hdr;
  945.   if (contents.depth != 1) {
  946.     OutputIconCursor = ColourCursor;
  947.     ResHdr colhdr(1, IconCursorID+1);
  948.     out << colhdr << contents << colhdr;
  949.   }
  950.   OutputIconCursor = CursorDirMap;
  951.   ResHdr dirhdr(12, id);
  952.   out << dirhdr << BinWord(0) << BinWord(2) << contents << dirhdr;
  953. }
  954. ///////////////////////////////////////////////////////////////
  955. //
  956. //  CursorDict::PrintOn
  957. //
  958. void CursorDict::PrintOn(ostream & out) const
  959. {
  960.   IconCursorID = 1;
  961.   //  output each of the cursors
  962.   for (int i = 0; i < GetSize(); i++)
  963.     out << GetDataAt (i);
  964. }
  965. ///////////////////////////////////////////////////////////////
  966. //
  967. //  Pattern::PrintOn
  968. //
  969. void Pattern::PrintOn(ostream & out) const
  970. {
  971.   ResHdr hdr(2, id);
  972.   out << hdr << contents << hdr;
  973. }
  974. ///////////////////////////////////////////////////////////////
  975. //
  976. //  PatternDict::PrintOn
  977. //
  978. void PatternDict::PrintOn(ostream & out) const
  979. {
  980.   OutputIconCursor = PixmapImage;
  981.   //  output each of the bitmaps
  982.   for (int i = 0; i < GetSize(); i++)
  983.     out << GetDataAt (i);
  984. }
  985. ///////////////////////////////////////////////////////////////
  986. //
  987. //  Image::PrintOn
  988. //
  989. void Image::PrintOn(ostream & out) const
  990. {
  991.   ResHdr hdr(2, id);
  992.   out << hdr << contents << hdr;
  993. }
  994. ///////////////////////////////////////////////////////////////
  995. //
  996. //  ImageDict::PrintOn
  997. //
  998. void ImageDict::PrintOn(ostream & out) const
  999. {
  1000.   OutputIconCursor = PixmapImage;
  1001.   //  output each of the bitmaps
  1002.   for (int i = 0; i < GetSize(); i++)
  1003.     out << GetDataAt (i);
  1004. }
  1005. ///////////////////////////////////////////////////////////////
  1006. //
  1007. //  DataResource::PrintOn
  1008. //
  1009. void DataResource::PrintOn(ostream & out) const
  1010. {
  1011.   ResHdr hdr(10, id);
  1012.   if (!textConverted.IsEmpty() && textConverted != "DATA")
  1013.     hdr.SetType(textConverted);
  1014.   out << hdr << data << hdr;
  1015. }
  1016. ///////////////////////////////////////////////////////////////
  1017. //
  1018. //  DataDict::PrintOn
  1019. //
  1020. void DataDict::PrintOn(ostream & out) const
  1021. {
  1022.   //  output each of the data resources
  1023.   for (int i = 0; i < GetSize(); i++)
  1024.     out << GetDataAt (i);
  1025. }
  1026. Control * MakeControl(Control * control, int id, int x, int y, int w, int h, char * str = NULL, int opts = 0)
  1027. {
  1028.   control->SetID(new ResourceID(id));
  1029.   control->SetPos(new Point(x, y));
  1030.   control->SetDim(new Point(w, h));
  1031.   if (str != NULL)
  1032.     control->SetText(new PString(str));
  1033.   if (opts != 0)
  1034.     control->SetOptions(opts);
  1035.   return control;
  1036. }
  1037. ///////////////////////////////////////////////////////////////
  1038. //
  1039. //  Backend
  1040. //
  1041. void ResourceFile::Backend(PFile & out)
  1042. {
  1043.   // Standard resources (always included)
  1044.   if (dialogDict.GetAt(PSTD_ID_DIALOG_OPEN_DIR) == NULL) {
  1045.     Layout * layout = new Layout("PModalDialog", 2);
  1046.     layout->SetPos (new Point(60, 40));
  1047.     layout->SetDim (new Point(170, 135));
  1048.     layout->SetText(new PString(""Directory Select""));
  1049.     layout->SetID(new ResourceID(PSTD_ID_DIALOG_OPEN_DIR));
  1050.     layout->AddControl(MakeControl(new LeftText(),     1090,    6,   6,  76,  9, ""Directory &Name:""));
  1051.     layout->AddControl(MakeControl(new EditBox(),      1159,    6,  16,  92, 12));
  1052.     layout->AddControl(MakeControl(new ListBox(),      1121,    6,  35,  92, 68, NULL, Special));
  1053.     layout->AddControl(MakeControl(new LeftText(),     1091,    6, 105,  92,  9, ""Dri&ves:""));
  1054.     layout->AddControl(MakeControl(new ChoiceBox(),    1137,    6, 115,  92, 68, NULL, Special));
  1055.     layout->AddControl(MakeControl(new PushButton(),      1,  114,   6,  50, 14, ""&Select"", DefaultButtonOption));
  1056.     layout->AddControl(MakeControl(new PushButton(),      2,  114,  26,  50, 14, ""Cancel""));
  1057.     layout->AddControl(MakeControl(new PushButton(),   1038,  114,  46,  50, 14, ""&Help""));
  1058.     layout->AddControl(MakeControl(new CheckBox(),     1040, 1000, 123,  54, 12, ""&Read Only""));
  1059.     layout->AddControl(MakeControl(new EditBox(),      1152, 1000,  16,  90, 12));
  1060.     layout->AddControl(MakeControl(new LeftText(),     1089, 1000, 110,  90,  9));
  1061.     layout->AddControl(MakeControl(new ChoiceBox(),    1136, 1000, 120,  90, 60));
  1062.     layout->AddControl(MakeControl(new LeftText(),     1088, 1000,   4, 999,  9));
  1063.     layout->AddControl(MakeControl(new ListBox(),      1120, 1000,  68,  34, 67));
  1064.     dialogDict.SetAt(PSTD_ID_DIALOG_OPEN_DIR, layout);
  1065.   }
  1066.   _setmode(out.GetHandle(), _O_BINARY);
  1067. #ifdef WIN32
  1068.   if (out.GetLength() == 0) {
  1069.     ResHdr hdr(0, 0);
  1070.     out << hdr << hdr;
  1071.   }
  1072. #endif
  1073.   out << stringDict;
  1074.   out << menubarDict;
  1075.   out << dialogDict;
  1076.   out << iconDict;
  1077.   out << cursorDict;
  1078.   out << patternDict;
  1079.   out << imageDict;
  1080.   out << dataDict;
  1081. }
  1082. // End WINDOWS.CXX ////////////////////////////////////////////////////////////