home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / pcutils / os2 / show3d / source / easy.cpp next >
Encoding:
C/C++ Source or Header  |  1995-12-31  |  32.1 KB  |  1,368 lines

  1. #include "easy.h"
  2.  
  3. #include <math.h>
  4.  
  5. static int window_invalid=0;
  6. static StandardWindow *actwindow;
  7.  
  8. // ******************* Debug tools **********************
  9.  
  10. void dumplong (long n)
  11. {    char s[256];
  12.     sprintf(s,"%ld, %lx",n,n);
  13.     WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,s,"Dump",0,
  14.         MB_OK);
  15. }
  16.  
  17. void dump (char *s)
  18. {    WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,s,"Dump",0,
  19.         MB_OK);
  20. }
  21.  
  22. // *********** Messages etc. ***************************
  23.  
  24. void Message (char *s, char *title)
  25. {    WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,s,title,0,
  26.         MB_OK|MB_INFORMATION);
  27. }
  28.  
  29. void Warning (char *s, char *title)
  30. {    WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,s,title,0,
  31.         MB_OK|MB_WARNING);
  32. }
  33.  
  34. int Question (char *s, char *title)
  35. {    return WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,s,title,0,
  36.         MB_YESNO|MB_QUERY);
  37. }
  38.  
  39. int QuestionAbort (char *s, char *title)
  40. {    return WinMessageBox(HWND_DESKTOP,HWND_DESKTOP,s,title,0,
  41.         MB_YESNOCANCEL|MB_QUERY);
  42. }
  43.  
  44. void Beep (int f, double sec)
  45. {    DosBeep(f,sec*1000);
  46. }
  47.  
  48. // **************** Threads **********************
  49.  
  50. void ThreadProc (Thread *s)
  51. {    int ret=s->call();
  52.     s->finished();
  53.     DosExit(EXIT_THREAD,ret);
  54. }
  55.  
  56. void Thread::start (Parameter p)
  57. {   stop();
  58.     P=p;
  59.     Started=1; Expected=0;
  60.     DosCreateThread(&Tid,(PFNTHREAD)ThreadProc,
  61.         Parameter(this),0,Stacksize);
  62. }
  63.  
  64. void Thread::stop ()
  65. {    if (Started) DosKillThread(Tid);
  66.     Started=0; Expected=0;
  67. }
  68.  
  69. void Thread::suspend ()
  70. {    if (Started) DosSuspendThread(Tid);
  71. }
  72.  
  73. void Thread::resume ()
  74. {    if (Started) DosResumeThread(Tid);
  75. }
  76.  
  77. void Thread::wait ()
  78. {   TID tid=Tid;
  79.     Expected=1;
  80.     if (Started) DosWaitThread(&tid,DCWW_WAIT);
  81. }
  82.  
  83. // **************** Time *************************
  84.  
  85. void Time::set ()
  86. {   long sec;
  87.     DosQuerySysInfo(QSV_TIME_LOW,QSV_TIME_LOW,
  88.         &sec,sizeof(ULONG));
  89.     Seconds=sec;
  90. }
  91.  
  92. // ********************* Strings ************************
  93.  
  94. long String::defaultsize=256;
  95.  
  96. String::String (char *text, LONG size)
  97. {   Size=strlen(text)+1;
  98.     if (Size<size+1) Size=size+1;
  99.     P=new char[Size];
  100.     strcpy(P,text);
  101. }
  102.  
  103. String::String (int id)
  104. {   char s[1024];
  105.     WinLoadString(program.hab(),NULLHANDLE,id,1022,s);
  106.     Size=strlen(s);
  107.     P=new char[Size+1];
  108.     strcpy(P,s);
  109. }
  110.  
  111.  
  112. String::String ()
  113. {   Size=defaultsize;
  114.     P=new char[Size+1];
  115.     *P=0;
  116. }
  117.  
  118. String::~String ()
  119. {    delete P;
  120. }
  121.  
  122. void String::copy (char *text, long size)
  123. {    delete P;
  124.     Size=strlen(text)+1;
  125.     if (Size<size+1) Size=size+1;
  126.     P=new char[Size+1];
  127.     strcpy(P,text);
  128. }
  129.  
  130. void String::copy (char *text)
  131. {    delete P;
  132.     Size=strlen(text)+1;
  133.     P=new char[Size+1];
  134.     strcpy(P,text);
  135. }
  136.  
  137. char *String::filename ()
  138. {    char *p=P+strlen(P);
  139.     while (p>P)
  140.     {    if (*p=='\\' || *p==':') return p+1;
  141.         p--;
  142.     }
  143.     return p;
  144. }
  145.  
  146. void String::stripfilename ()
  147. {    *filename()=0;
  148. }
  149.  
  150. int String::todouble (double &x)
  151. {    int n;
  152.     if (sscanf(P,"%lg%n",&x,&n)==0) return 0;
  153.     char *p=P+n;
  154.     if (*p) return 0;
  155.     else return 1;
  156. }
  157.  
  158. int String::tolong (long &x)
  159. {    int n;
  160.     if (sscanf(P,"%ld%n",&x,&n)==0) return 0;
  161.     char *p=P+n;
  162.     if (*p) return 0;
  163.     else return 1;
  164. }
  165.  
  166. // ****************** Rectangle *************************
  167.  
  168. void Rectangle::minsize (LONG wmin, LONG hmin)
  169. {    if (W<0 && -W<wmin) W=-wmin;
  170.     else if (W>=0 && W<wmin) W=wmin;
  171.     if (H<0 && -H<hmin) H=-hmin;
  172.     else if (H>=0 && H<hmin) H=hmin;
  173. }
  174.  
  175. void Rectangle::hrescale (double scale)
  176. {    H=(LONG)(scale*abs(W))*(H<0?-1:1);
  177. }
  178.  
  179. void Rectangle::wrescale (double scale)
  180. {    W=(LONG)(scale*abs(H))*(W<0?-1:1);
  181. }
  182.  
  183. // ******************** Program *************************
  184.  
  185. MRESULT EXPENTRY MainWindowProc (HWND hwnd, ULONG msg,
  186.     MPARAM mp1, MPARAM mp2)
  187. {    StandardWindow *window;
  188.     clicktype click;
  189.     if (window_invalid) window=actwindow;
  190.     else window=(StandardWindow *)WinQueryWindowPtr(hwnd,QWL_USER);
  191.     POINTS *points;
  192.     switch (msg)
  193.     {   case WM_CREATE :
  194.             window->Handle=hwnd;
  195.             break;
  196.         case WM_PRESPARAMCHANGED :
  197.             window->pres_changed();
  198.             goto def;
  199.         case WM_PAINT :
  200.             {    RedrawPS ps(hwnd,*window);
  201.                 window->redraw(ps);
  202.             }
  203.             break;
  204.         case WM_SIZE :
  205.             if (SHORT1FROMMP(mp2)==0) goto def;
  206.             if (window->Width==SHORT1FROMMP(mp2) &&
  207.                 window->Height==SHORT2FROMMP(mp2)) goto def;
  208.             window->Width=SHORT1FROMMP(mp2);
  209.             window->Height=SHORT2FROMMP(mp2);
  210.             window->sized();
  211.             break;
  212.         case WM_CHAR :
  213.             if (window->key(SHORT1FROMMP(mp1),SHORT1FROMMP(mp2),
  214.                 SHORT2FROMMP(mp2))) break;
  215.             goto def;
  216.         case WM_HSCROLL :
  217.             if (window->hscrolled(SHORT2FROMMP(mp2),SHORT1FROMMP(mp2)))
  218.                 break;
  219.             goto def;
  220.         case WM_VSCROLL :
  221.             if (window->vscrolled(SHORT2FROMMP(mp2),SHORT1FROMMP(mp2)))
  222.                 break;
  223.             goto def;
  224.         case WM_BUTTON1CLICK :
  225.             click=button1; goto button;
  226.         case WM_BUTTON2CLICK :
  227.             click=button2; goto button;
  228.         case WM_BUTTON3CLICK :
  229.             click=button3; goto button;
  230.         case WM_BUTTON1UP :
  231.             click=button1up; goto button;
  232.         case WM_BUTTON2UP :
  233.             click=button2up; goto button;
  234.         case WM_BUTTON3UP :
  235.             click=button3up; goto button;
  236.         case WM_BUTTON1DOWN :
  237.             click=button1down; goto button;
  238.         case WM_BUTTON2DOWN :
  239.             click=button2down; goto button;
  240.         case WM_BUTTON3DOWN :
  241.             click=button3down; goto button;
  242.         case WM_BUTTON1DBLCLK :
  243.             click=button1double; goto button;
  244.         case WM_BUTTON2DBLCLK :
  245.             click=button2double; goto button;
  246.         case WM_MOUSEMOVE :
  247.             WinSetPointer(HWND_DESKTOP,window->New);
  248.             click=mousemove; goto button;
  249.         case WM_BUTTON3DBLCLK :
  250.             click=button3double;
  251.             button: points=(POINTS *)&mp1;
  252.             window->clicked(points->x,points->y,click);
  253.             break;
  254.         case WM_COMMAND :
  255.             if (window->Windowmenu)
  256.                 if (window->Windowmenu->call(SHORT1FROMMP(mp1)))
  257.                     break;
  258.             goto def;
  259.         case WM_SHOW :
  260.             window->Visible=SHORT1FROMMP(mp1);
  261.             goto def;
  262.         case WM_CLOSE :
  263.             if (window->close()) goto def;
  264.             break;
  265.         case WM_TIMER :
  266.             window->timer(SHORT1FROMMP(mp1));
  267.             break;
  268.         default :
  269.             def: return WinDefWindowProc(hwnd,msg,mp1,mp2);
  270.     }
  271.     return (MRESULT)FALSE;
  272. }
  273.  
  274. Program::Program ()
  275. {     Hab=WinInitialize(0);
  276.     Hmq=WinCreateMsgQueue(Hab,0);
  277.     WinRegisterClass(Hab,"EasyMainWindow",MainWindowProc,
  278.         CS_SIZEREDRAW,sizeof(StandardWindow *));
  279. }
  280.  
  281. Program::~Program ()
  282. {    WinDestroyMsgQueue(Hmq);
  283.     WinTerminate(Hab);
  284. }
  285.  
  286. inline int Program::getmessage ()
  287. {    return WinGetMsg(Hab,&Qmsg,0L,0,0);
  288. }
  289.  
  290. inline void Program::dispatch ()
  291. {    WinDispatchMsg(Hab,&Qmsg);
  292. }
  293.  
  294. void Program::loop ()
  295. {    while(getmessage())
  296.         dispatch();
  297. }
  298.  
  299. // ************** Window ******************************
  300.  
  301. Window::Window ()
  302. {    New=Old=WinQuerySysPointer(HWND_DESKTOP,pointer_arrow,TRUE);
  303. }
  304.  
  305. void Window::size (long w, long h)
  306. {    WinSetWindowPos(Handle,NULLHANDLE,0,0,
  307.         w,h,SWP_SIZE);
  308. }
  309.  
  310. void Window::pos (long x, long y)
  311. {    WinSetWindowPos(Handle,NULLHANDLE,x,y,
  312.         0,0,SWP_MOVE);
  313. }
  314.  
  315. void Window::setpointer (pointertype p)
  316. {    New=WinQuerySysPointer(HWND_DESKTOP,p,FALSE);
  317.     WinSetPointer(HWND_DESKTOP,New);
  318. }
  319.  
  320. void Window::resetpointer ()
  321. {    WinSetPointer(HWND_DESKTOP,Old);
  322.     New=Old;
  323. }
  324.  
  325. void Window::showpointer ()
  326. {    WinShowPointer(HWND_DESKTOP,TRUE);
  327. }
  328.  
  329. void Window::hidepointer ()
  330. {    WinShowPointer(HWND_DESKTOP,FALSE);
  331. }
  332.  
  333. void Window::pos (long &x, long &y, long &w, long &h)
  334. {   SWP p;
  335.     WinQueryWindowPos(Handle,&p);
  336.     x=p.x; y=p.y; w=p.cx; h=p.cy;
  337. }
  338.  
  339. // ************* Standard Window ***********************
  340.  
  341. void StandardWindow::size (LONG w, LONG h)
  342. {   RECTL r;
  343.     r.xLeft=r.yBottom=0; r.xRight=w; r.yTop=h;
  344.     WinCalcFrameRect(FrameHandle,&r,FALSE);
  345.     WinSetWindowPos(FrameHandle,NULLHANDLE,0,0,
  346.         r.xRight-r.xLeft,r.yTop-r.yBottom,SWP_SIZE);
  347. }
  348.  
  349. void StandardWindow::init ()
  350. {   window_invalid=1;
  351.     actwindow=this;
  352.     FrameHandle=WinCreateStdWindow(HWND_DESKTOP,
  353.         WS_VISIBLE,&Flags,"EasyMainWindow",
  354.         (char *)Name,WS_VISIBLE,(HMODULE)0,Id,&Handle);
  355.     WinSetWindowPtr(Handle,QWL_USER,this);
  356.     window_invalid=0;
  357.     Windowmenu=NULL;
  358.     Visible=1;
  359. }
  360.  
  361. StandardWindow::~StandardWindow ()
  362. {    WinDestroyWindow(FrameHandle);
  363. }
  364.  
  365. StandardWindow::StandardWindow (int id, char *name, ULONG flags)
  366.     : Name(name)
  367. {    Id=id; Flags=flags;
  368. }
  369.  
  370. void StandardWindow::top ()
  371. {    WinSetWindowPos(FrameHandle,
  372.         HWND_TOP,0,0,0,0,SWP_ZORDER);
  373.     WinSetFocus(HWND_DESKTOP,Handle);
  374. }
  375.  
  376. int StandardWindow::rubberbox (LONG x, LONG y, clicktype click,
  377.     Rectangle &R, LONG wmin, LONG hmin, double wscale, double hscale)
  378. {   WindowPS ps(*this);
  379.     ps.mix(FM_XOR);
  380.     switch (click)
  381.     {    case button1down :
  382.             capture();
  383.             Rubber=1;
  384.             R=Rectangle(x,y,wmin,hmin);
  385.             ps.frame(R,0,CLR_GREEN);
  386.             return RUBBER_START;
  387.         case mousemove :
  388.             if (!Rubber) break;
  389.             ps.frame(R,0,CLR_GREEN);
  390.             R.resize(x-R.x(),y-R.y());
  391.             R.minsize(hmin,wmin);
  392.             if (wscale>0) R.wrescale(wscale);
  393.             if (hscale>0) R.hrescale(hscale);
  394.             ps.frame(R,0,CLR_GREEN);
  395.             Rubber=2;
  396.             break;
  397.         case button1up :
  398.             capture(0);
  399.             if (!Rubber || Rubber==1) return RUBBER_CANCEL;
  400.             ps.frame(R,0,CLR_GREEN);
  401.             Rubber=0;
  402.             if (abs(y-R.y())>=hmin) return RUBBER_DONE;
  403.             else return RUBBER_CANCEL;
  404.     }
  405.     return RUBBER_ZERO;
  406. }
  407.  
  408. void StandardWindow::vscroll (int pos, int min, int max)
  409. {    HWND h=WinWindowFromID(FrameHandle,FID_VERTSCROLL);
  410.     WinSendMsg(h,SBM_SETSCROLLBAR,MPFROMSHORT(pos),
  411.         MPFROM2SHORT(min,max));
  412. }
  413.  
  414. void StandardWindow::hscroll (int pos, int min, int max)
  415. {    HWND h=WinWindowFromID(FrameHandle,FID_HORZSCROLL);
  416.     WinSendMsg(h,SBM_SETSCROLLBAR,MPFROMSHORT(pos),
  417.         MPFROM2SHORT(min,max));
  418. }
  419.  
  420. void StandardWindow::title (char *s)
  421. {    HWND h=WinWindowFromID(FrameHandle,FID_TITLEBAR);
  422.     WinSetWindowText(h,s);
  423. }
  424.  
  425. // ************* Menus ************************************
  426.  
  427. Menu::~Menu ()
  428. {    while (Mp)
  429.     {    delete Mp;
  430.         Mp=Mp->next();
  431.     }
  432. }
  433.  
  434. int Menu::call (int command)
  435. {    Menuentry *m=Mp;
  436.     Command=command;
  437.     while (m)
  438.         if (m->command()==command)
  439.         {    m->call(command);
  440.             return 1;
  441.         }
  442.         else m=m->next();
  443.     return 0;
  444. }
  445.  
  446. void Menu::enable (int id, int flag)
  447. {    HWND handle=WinWindowFromID(W->framehandle(),FID_MENU);
  448.     WinSendMsg(handle,MM_SETITEMATTR,
  449.         MPFROM2SHORT(id,TRUE),MPFROM2SHORT(MIA_DISABLED,
  450.         flag?0:MIA_DISABLED));
  451. }
  452.  
  453. void Menu::check (int id, int flag)
  454. {    HWND handle=WinWindowFromID(W->framehandle(),FID_MENU);
  455.     WinSendMsg(handle,MM_SETITEMATTR,
  456.         MPFROM2SHORT(id,TRUE),MPFROM2SHORT(MIA_CHECKED,
  457.         flag?MIA_CHECKED:0));
  458. }
  459.  
  460. // ************* Presentation Space class (PS) *************
  461.  
  462. void PS::clip (long x, long y, long w, long h)
  463. {    RECTL r;
  464.     r.xLeft=x+X; r.xRight=x+X+w-1; r.yBottom=y+Y; r.yTop=y+Y+h-1;
  465.     GpiIntersectClipRectangle(Handle,&r);
  466.     S.cx=w; S.cy=h;
  467. }
  468.  
  469. void PS::setcolor (int index, Rgb rgb, int pure)
  470. {    LONG table[1];
  471.     table[0]=rgb;
  472.     GpiCreateLogColorTable(Handle,pure?LCOL_PURECOLOR:0,
  473.                 LCOLF_CONSECRGB,index,1,(PLONG)table);
  474. }
  475.  
  476. void PS::directcolor (int pure)
  477. {    GpiCreateLogColorTable(Handle,pure?LCOL_PURECOLOR:0,
  478.                 LCOLF_RGB,0,0,NULL);
  479. }
  480.  
  481. void PS::defaultcolors ()
  482. {    GpiCreateLogColorTable(Handle,LCOL_RESET,0,0,0,NULL);
  483. }
  484.  
  485. void PS::move (LONG c, LONG r, ULONG col)
  486. {   color(col);
  487.     P.x=c+X; P.y=r+Y; GpiMove(Handle,&P);
  488. }
  489.  
  490. void PS::linerel (LONG w, LONG h, ULONG col)
  491. {   color(col);
  492.     P.x+=w; P.y+=h; GpiLine(Handle,&P);
  493. }
  494.  
  495. void PS::lineto (LONG c, LONG r, ULONG col)
  496. {   color(col);
  497.     P.x=c+X; P.y=r+Y; GpiLine(Handle,&P);
  498. }
  499.  
  500. void PS::point (LONG c, LONG r, ULONG col)
  501. {   color(col);
  502.     P.x=c+X; P.y=r+Y; GpiSetPel(Handle,&P);
  503. }
  504.  
  505. void PS::text (char *s, ULONG col, ULONG al, ULONG val)
  506. {    color(col);
  507.     GpiSetTextAlignment(Handle,al,val);
  508.     GpiCharString(Handle,strlen(s),s);
  509. }
  510.  
  511. void PS::textbox (char *text, long &width, long &height)
  512. {   POINTL pts[4];
  513.     GpiQueryTextBox(Handle,strlen(text),text,4,pts);
  514.     width=pts[2].x-pts[0].x;
  515.     height=pts[2].y-pts[0].y;
  516. }
  517.  
  518. double PS::textextend (char *text, double vx, double vy)
  519. {   POINTL pts[4];
  520.     int i;
  521.     double emin,emax,r,h;
  522.     GpiQueryTextBox(Handle,strlen(text),text,4,pts);
  523.     r=sqrt(vx*vx+vy*vy); vx/=r; vy/=r;
  524.     pts[0].x--; pts[1].x--;
  525.     pts[2].x++; pts[2].x++;
  526.     emin=emax=vx*pts[0].x+vy*pts[0].y;
  527.     for (i=1; i<4; i++)
  528.     {    h=vx*pts[i].x+vy*pts[i].y;
  529.         if (h<emin) emin=h;
  530.         else if (h>emax) emax=h;
  531.     }
  532.     return emax-emin;
  533. }
  534.  
  535. void PS::frame (LONG w, LONG h, int r, ULONG col)
  536. {    color(col);
  537.     P.x+=w+1; P.y+=h+1; GpiBox(Handle,DRO_OUTLINE,&P,r,r);
  538. }
  539.  
  540. void PS::area (LONG w, LONG h, int r, ULONG col)
  541. {    color(col);
  542.     GpiSetBackMix(Handle,BM_OVERPAINT);
  543.     GpiSetPattern(Handle,PATSYM_SOLID);
  544.     P.x+=w+1; P.y+=h+1; GpiBox(Handle,DRO_FILL,&P,r,r);
  545. }
  546.  
  547. void PS::framedarea (LONG w, LONG h, int r, ULONG col)
  548. {    color(col);
  549.     GpiSetBackMix(Handle,BM_OVERPAINT);
  550.     GpiSetPattern(Handle,PATSYM_BLANK);
  551.     P.x+=w+1; P.y+=h+1; GpiBox(Handle,DRO_OUTLINEFILL,&P,r,r);
  552. }
  553.  
  554. void PS::frame (Rectangle &R, int r, ULONG col)
  555. {    move(R.x1(),R.y1());
  556.     frame(abs(R.w()),abs(R.h()),r,col);
  557. }
  558.  
  559. void PS::area (Rectangle &R, int r, ULONG col)
  560. {    move(R.x1(),R.y1());
  561.     area(abs(R.w()),abs(R.h()),r,col);
  562. }
  563.  
  564. void PS::framedarea (Rectangle &R, int r, ULONG col)
  565. {    move(R.x1(),R.y1());
  566.     framedarea(abs(R.w()),abs(R.h()),r,col);
  567. }
  568.  
  569. void PS::mark (LONG c, LONG r, ULONG type, ULONG col)
  570. {   color(col);
  571.     GpiSetMarker(Handle,type);
  572.     P.x=c+X; P.y=r+Y; GpiMarker(Handle,&P);
  573. }
  574.  
  575. void PS::circle (LONG c, LONG r, LONG rad, double factor, ULONG col)
  576. {   ARCPARAMS p;
  577.     p.lP=rad; p.lS=0;
  578.     p.lQ=rad*factor; p.lR=0;
  579.     GpiSetArcParams(Handle,&p);
  580.     move(c,r);
  581.     color(col);
  582.     GpiFullArc(Handle,DRO_OUTLINE,65536l);
  583. }
  584.  
  585. void PS::arc (LONG c, LONG r, LONG rad, double factor,
  586.     double phi1, double phi2, ULONG col)
  587. {   ARCPARAMS p;
  588.     p.lP=rad; p.lS=0;
  589.     p.lQ=rad*factor; p.lR=0;
  590.     GpiSetArcParams(Handle,&p);
  591.     move(c,r);
  592.     color(col);
  593.     double delta;
  594.     if (phi1<0) phi1+=360;
  595.     if (phi2<0) phi2+=360;
  596.     if (phi2>=phi1) delta=phi2-phi1;
  597.     else delta=phi2+360-phi1;
  598.     GpiSetLineType(Handle,LINETYPE_INVISIBLE);
  599.     GpiPartialArc(Handle,&P,65536l,phi1*65536l,0);
  600.     GpiSetLineType(Handle,LINETYPE_SOLID);
  601.     GpiPartialArc(Handle,&P,65536l,
  602.         phi1*65536l,delta*65536l);
  603. }
  604.  
  605. void PS::setfont (Font &font, int id)
  606. {   SIZEF s;
  607.     double f;
  608.     GpiCreateLogFont(Handle,NULL,id,font.fat());
  609.     GpiSetCharSet(Handle,id);
  610.     if (font.pointsize()!=font.nominalsize())
  611.     {    GpiQueryCharBox(Handle,&s);
  612.         f=font.pointsize()/font.nominalsize();
  613.         s.cx*=f; s.cy*=f;
  614.         GpiSetCharBox(Handle,&s);
  615.     }
  616. }
  617.  
  618. void PS::image (long w, long h, unsigned char *data)
  619. {   SIZEL s;
  620.     s.cx=w; s.cy=h;
  621.     GpiImage(Handle,0,&s,((w-1)/8+1)*h,data);
  622. }
  623.  
  624. //************ Bitmaps Presentation Spaces *****************
  625.  
  626. BitmapPS::BitmapPS (Window &window)
  627. {    PSZ pszData[4]={"Display",NULL,NULL,NULL};
  628.     BITMAPINFOHEADER2 bmp;
  629.     LONG alData[2],size;
  630.     DeviceHandle=DevOpenDC(program.hab(),OD_MEMORY,"*",4,
  631.         (PDEVOPENDATA)pszData,NULLHANDLE);
  632.     S.cx=window.width(); S.cy=window.height();
  633.     Handle=GpiCreatePS(program.hab(),DeviceHandle,&S,
  634.         PU_PELS|GPIA_ASSOC|GPIT_MICRO);
  635.     GpiQueryDeviceBitmapFormats(Handle,2,(PLONG)alData);
  636.     bmp.cbFix=(ULONG)sizeof(BITMAPINFOHEADER2);
  637.     bmp.cx=S.cx; bmp.cy=S.cy;
  638.     Planes=bmp.cPlanes=alData[0];
  639.     Colorbits=bmp.cBitCount=alData[1];
  640.     bmp.ulCompression=BCA_UNCOMP;
  641.     bmp.cbImage=(((S.cx*(1<<bmp.cPlanes)*(1<<bmp.cBitCount))+31)
  642.         /32)*S.cy;
  643.     bmp.cxResolution=70; bmp.cyResolution=70;
  644.     bmp.cclrUsed=2; bmp.cclrImportant=0;
  645.     bmp.usUnits=BRU_METRIC; bmp.usReserved=0;
  646.     bmp.usRecording=BRA_BOTTOMUP; bmp.usRendering=BRH_NOTHALFTONED;
  647.     bmp.cSize1=0; bmp.cSize2=0;
  648.     bmp.ulColorEncoding=BCE_RGB; bmp.ulIdentifier=0;
  649.     size=sizeof(BITMAPINFO2)+
  650.         (sizeof(RGB2)*(1<<bmp.cPlanes)*(1<<bmp.cBitCount));
  651.     if (DosAllocMem((PVOID *)&Info,size,PAG_COMMIT|PAG_READ|PAG_WRITE))
  652.     {    Valid=0;
  653.         GpiDestroyPS(Handle);
  654.         DevCloseDC(DeviceHandle);
  655.     }
  656.     else Valid=1;
  657.     Info->cbFix=bmp.cbFix;
  658.     Info->cx=bmp.cx; Info->cy=bmp.cy;
  659.     Info->cPlanes=bmp.cPlanes; Info->cBitCount=bmp.cBitCount;
  660.     Info->ulCompression=BCA_UNCOMP;
  661.     Info->cbImage=((S.cx+31)/32)*S.cy;
  662.     Info->cxResolution=70; Info->cyResolution=70;
  663.     Info->cclrUsed=2; Info->cclrImportant=0;
  664.     Info->usUnits=BRU_METRIC;
  665.     Info->usReserved=0;
  666.     Info->usRecording=BRA_BOTTOMUP;
  667.     Info->usRendering=BRH_NOTHALFTONED;
  668.     Info->cSize1=0; Info->cSize2=0;
  669.     Info->ulColorEncoding=BCE_RGB; Info->ulIdentifier=0;
  670.     BitmapHandle=GpiCreateBitmap(Handle,&bmp,FALSE,NULL,Info);
  671.     GpiSetBitmap(Handle,BitmapHandle);
  672.     GpiErase(Handle);
  673. }
  674.  
  675. BitmapPS::BitmapPS (long w, long h)
  676. {    PSZ pszData[4]={"Display",NULL,NULL,NULL};
  677.     BITMAPINFOHEADER2 bmp;
  678.     LONG alData[2],size;
  679.     DeviceHandle=DevOpenDC(program.hab(),OD_MEMORY,"*",4,
  680.         (PDEVOPENDATA)pszData,NULLHANDLE);
  681.     S.cx=w; S.cy=h;
  682.     Handle=GpiCreatePS(program.hab(),DeviceHandle,&S,
  683.         PU_PELS|GPIA_ASSOC|GPIT_MICRO);
  684.     GpiQueryDeviceBitmapFormats(Handle,2,(PLONG)alData);
  685.     bmp.cbFix=(ULONG)sizeof(BITMAPINFOHEADER2);
  686.     bmp.cx=S.cx; bmp.cy=S.cy;
  687.     Planes=bmp.cPlanes=alData[0];
  688.     Colorbits=bmp.cBitCount=alData[1];
  689.     bmp.ulCompression=BCA_UNCOMP;
  690.     bmp.cbImage=(((S.cx*(1<<bmp.cPlanes)*(1<<bmp.cBitCount))+31)
  691.         /32)*S.cy;
  692.     bmp.cxResolution=70; bmp.cyResolution=70;
  693.     bmp.cclrUsed=2; bmp.cclrImportant=0;
  694.     bmp.usUnits=BRU_METRIC; bmp.usReserved=0;
  695.     bmp.usRecording=BRA_BOTTOMUP; bmp.usRendering=BRH_NOTHALFTONED;
  696.     bmp.cSize1=0; bmp.cSize2=0;
  697.     bmp.ulColorEncoding=BCE_RGB; bmp.ulIdentifier=0;
  698.     size=sizeof(BITMAPINFO2)+
  699.         (sizeof(RGB2)*(1<<bmp.cPlanes)*(1<<bmp.cBitCount));
  700.     if (DosAllocMem((PVOID *)&Info,size,PAG_COMMIT|PAG_READ|PAG_WRITE))
  701.     {    Valid=0;
  702.         GpiDestroyPS(Handle);
  703.         DevCloseDC(DeviceHandle);
  704.     }
  705.     else Valid=1;
  706.     Info->cbFix=bmp.cbFix;
  707.     Info->cx=bmp.cx; Info->cy=bmp.cy;
  708.     Info->cPlanes=bmp.cPlanes; Info->cBitCount=bmp.cBitCount;
  709.     Info->ulCompression=BCA_UNCOMP;
  710.     Info->cbImage=((S.cx+31)/32)*S.cy;
  711.     Info->cxResolution=70; Info->cyResolution=70;
  712.     Info->cclrUsed=2; Info->cclrImportant=0;
  713.     Info->usUnits=BRU_METRIC;
  714.     Info->usReserved=0;
  715.     Info->usRecording=BRA_BOTTOMUP;
  716.     Info->usRendering=BRH_NOTHALFTONED;
  717.     Info->cSize1=0; Info->cSize2=0;
  718.     Info->ulColorEncoding=BCE_RGB; Info->ulIdentifier=0;
  719.     BitmapHandle=GpiCreateBitmap(Handle,&bmp,FALSE,NULL,Info);
  720.     GpiSetBitmap(Handle,BitmapHandle);
  721.     GpiErase(Handle);
  722. }
  723.  
  724. BitmapPS::~BitmapPS ()
  725. {   if (!Valid) return;
  726.     GpiDeleteBitmap(BitmapHandle);
  727.     DosFreeMem(Info);
  728.     GpiDestroyPS(Handle);
  729.     DevCloseDC(DeviceHandle);
  730. }
  731.  
  732. void BitmapPS::copy (PS &ps, int mode, long x, long y)
  733. {    POINTL a[4];
  734.     RECTL r;
  735.     r.xLeft=a[0].x=x; r.yBottom=a[0].y=y;
  736.     r.xRight=a[1].x=x+S.cx; r.yTop=a[1].y=y+S.cy;
  737.     a[2].x=0; a[2].y=0;
  738.     if (!GpiRectVisible(ps.handle(),&r)) return;
  739.     GpiBitBlt(ps.handle(),Handle,3,a,mode,BBO_IGNORE);
  740. }
  741.  
  742. void BitmapPS::save (char *filename)
  743. {    FILE *f;
  744.     BITMAPFILEHEADER2 bfh;
  745.     char *buffer;
  746.     PBITMAPINFO2 pbmi;
  747.     long size,colorsize,hdsize=20;
  748.     ULONG compression=BCA_UNCOMP;
  749.     f=fopen(filename,"wb");
  750.     if (!f)
  751.     {   Warning("Could not open\nthat file.","Save Error");
  752.         return;
  753.     }
  754.     bfh.usType=BFT_BMAP;
  755.     colorsize=((Colorbits<=8)?(1<<Colorbits):256)*sizeof(RGB2);
  756.     size=((width()*Colorbits+31)/32)*4*height();
  757.     bfh.offBits=14+hdsize+colorsize;
  758.     bfh.cbSize=14+hdsize+colorsize+size;
  759.     buffer=(char *)malloc(size);
  760.     pbmi=(PBITMAPINFO2)malloc(16+colorsize);
  761.     memset(pbmi,0,sizeof(BITMAPINFOHEADER2));
  762.     pbmi->cbFix=hdsize;
  763.     pbmi->cPlanes=1;
  764.     pbmi->cBitCount=Colorbits;
  765.     pbmi->ulCompression=compression;
  766.     if (GpiQueryBitmapBits(handle(),0,height(),buffer,pbmi)!=height())
  767.     {   Warning("Bitmap Save Error!","Error");
  768.         goto end;
  769.     }
  770.     fwrite((char *)&bfh,14,1,f);
  771.     fwrite((char *)pbmi,hdsize+colorsize,1,f);
  772.     fwrite(buffer,1,size,f);
  773.     end: free(pbmi);
  774.     free(buffer);
  775.     fclose(f);
  776. }
  777.  
  778. // ************ Printer ***********************
  779.  
  780. Queues::Queues (char *name) : Queues(0),NQueues(0)
  781. {   int Default=0,i;
  782.     all();
  783.     if (NQueues==0) return;
  784.     if (name[0])
  785.     {    for (i=0; i<NQueues; i++)
  786.             if (!strcmp(name,Queues[i].pszName))
  787.             {    Default=i;
  788.                 break;
  789.             }
  790.     }
  791.     memmove(&ChosenQueue,Queues+Default,sizeof(PRQINFO3));
  792.     delete Queues;
  793.     Queues=0;
  794. }
  795.  
  796. PRQINFO3 *Queues::all ()
  797. {   ULONG ret,size;
  798.     if (Queues) delete Queues;
  799.     SplEnumQueue(NULL,3,Queues,0,
  800.         &ret,&NQueues,&size,NULL);
  801.     if (NQueues==0) return 0;
  802.     Queues=(PRQINFO3 *)(new char[size]);
  803.     SplEnumQueue(NULL,3,Queues,size,
  804.         &ret,&NQueues,&size,NULL);
  805.     return Queues;
  806. }
  807.  
  808. PrinterPS::PrinterPS (Queues &q, char *name, int op)
  809.     : Valid(0),Myname(name),Open(0)
  810. {    memmove(&Queue,q.chosen(),sizeof(PRQINFO3));
  811.     Valid.set();
  812.     if (op) open();
  813. }
  814.  
  815. PrinterPS::PrinterPS (char *name, int op)
  816.     : Valid(0),Myname(name),Open(0)
  817. {    Queues queues;
  818.     if (queues.number()<1) return;
  819.     Valid.set();
  820.     memmove(&Queue,queues.chosen(),sizeof(PRQINFO3));
  821.     if (op) open();
  822. }
  823.  
  824. void PrinterPS::open ()
  825. {   if (Open) return;
  826.     Dos.pszLogAddress=Queue.pszName;
  827.     Dos.pszDriverName=Queue.pszDriverName;
  828.     *strchr(Dos.pszDriverName,'.')=0;
  829.     Dos.pdriv=Queue.pDriverData;
  830.     Dos.pszDataType="PM_Q_STD";
  831.     Dos.pszComment=Myname;
  832.     Dos.pszQueueProcName=Queue.pszPrProc;
  833.     Dos.pszQueueProcParams=NULL;
  834.     Dos.pszSpoolerParams=NULL;
  835.     Dos.pszNetworkParams=NULL;
  836.     HandlePrinter=DevOpenDC(program.hab(),OD_QUEUED,"*",9,
  837.         (PDEVOPENDATA)&Dos,(HDC)0);
  838.     if (HandlePrinter==DEV_ERROR)
  839.     {   Valid.clear(); return;
  840.     }
  841.     Handle=GpiCreatePS(program.hab(),HandlePrinter,&S,
  842.         PU_PELS|GPIA_ASSOC);
  843.     if (DevEscape(HandlePrinter,DEVESC_STARTDOC,0,0,0,0)!=DEV_OK)
  844.     {    Valid.clear(); return;
  845.     }
  846.     LONG alArray [CAPS_WIDTH_IN_CHARS];
  847.     DevQueryCaps(HandlePrinter,CAPS_FAMILY,CAPS_WIDTH_IN_CHARS,
  848.         (PLONG)alArray);
  849.     S.cx=alArray[CAPS_WIDTH];
  850.     S.cy=alArray[CAPS_HEIGHT];
  851.     Open.set();
  852. }
  853.  
  854. void PrinterPS::close ()
  855. {   if (!Open) return;
  856.     DevEscape(HandlePrinter,DEVESC_ENDDOC,0,0,0,0);
  857.     DevCloseDC(HandlePrinter);
  858.     GpiDestroyPS(Handle);
  859.     Open.clear();
  860. }
  861.  
  862. // ************* Metafiles **********************
  863.  
  864. MetafilePS::MetafilePS (Window &window)
  865. {   DEVOPENSTRUC dos;
  866.     DEVOPENSTRUC dop;
  867.     char *p;
  868.     dop.pszLogAddress=(PSZ)NULL;
  869.     dop.pszDriverName="DISPLAY";
  870.     Hdc=DevOpenDC(program.hab(),
  871.         OD_METAFILE,"*",2L,(PDEVOPENDATA)&dop,0);
  872.     S.cx=window.width(); S.cy=window.height();
  873.     Handle=GpiCreatePS(program.hab(),Hdc,&S,PU_PELS|GPIA_ASSOC);
  874. }
  875.  
  876. MetafilePS::~MetafilePS ()
  877. {    close();
  878. }
  879.  
  880. void MetafilePS::close ()
  881. {   if (Handle==NULLHANDLE) return;
  882.     GpiAssociate(Handle,NULLHANDLE);
  883.     GpiDestroyPS(Handle);
  884.     Metafilehandle=DevCloseDC(Hdc);
  885.     Handle=NULLHANDLE;
  886. }
  887.  
  888. //***************** Bitmap Resources ***********************
  889.  
  890. Bitmap::Bitmap (int id, int width, int height)
  891. {    PSZ pszData[4]={"Display",NULL,NULL,NULL};
  892.     DeviceHandle=DevOpenDC(program.hab(),OD_MEMORY,"*",4,
  893.         (PDEVOPENDATA)pszData,NULLHANDLE);
  894.     S.cx=width; S.cy=height;
  895.     PsHandle=GpiCreatePS(program.hab(),DeviceHandle,&S,
  896.         PU_PELS|GPIA_ASSOC|GPIT_MICRO);
  897.     Handle=GpiLoadBitmap(PsHandle,0,id,0,0);
  898. }
  899.  
  900. Bitmap::~Bitmap ()
  901. {   GpiDestroyPS(PsHandle);
  902.     DevCloseDC(DeviceHandle);
  903.     GpiDeleteBitmap(Handle);
  904. }
  905.  
  906. //******************* Help ******************************
  907.  
  908.  
  909. Help::Help (StandardWindow &window,
  910.     int id, char *filename, char *title)
  911. {    HELPINIT hini;
  912.     hini.cb=sizeof(HELPINIT);
  913.     hini.ulReturnCode=0L;
  914.     hini.pszTutorialName=(PSZ)NULL;
  915.     hini.phtHelpTable=
  916.         (PHELPTABLE)MAKELONG(id,0xFFFF);
  917.     hini.hmodHelpTableModule=(HMODULE)0;
  918.     hini.hmodAccelActionBarModule=(HMODULE)0;
  919.     hini.idAccelTable=0;
  920.     hini.idActionBar=0;
  921.     hini.pszHelpWindowTitle=title;
  922.     hini.fShowPanelId = CMIC_HIDE_PANEL_ID;
  923.     hini.pszHelpLibraryName=filename;
  924.     Handle=WinCreateHelpInstance(program.hab(),&hini);
  925.     if (!Handle) { Valid=0; return; }
  926.     Valid=1;
  927.     WinAssociateHelpInstance(Handle,window.framehandle());
  928. }
  929.  
  930. // ****************** Dialogs *************************
  931.  
  932. static Dialog *activedlg,*dlgs=0;
  933.  
  934. static MRESULT EXPENTRY dialogproc (HWND hwnd, ULONG msg,
  935.     MPARAM mp1, MPARAM mp2)
  936. {   Dialogitem *item;
  937.     Dialog *dlg,*dlg1;
  938.     int result;
  939.     if (!activedlg) // search dialog using window handle
  940.     {    dlg=dlgs;
  941.         while (dlg)
  942.         {    if (dlg->Handle==hwnd) break;
  943.             dlg=dlg->Next;
  944.         }
  945.         if (!dlg) // should not happen
  946.             return WinDefDlgProc(hwnd,msg,mp1,mp2);
  947.     }
  948.     else dlg=activedlg;
  949.     switch (msg)
  950.     {   case WM_INITDLG : // initialize activedlg
  951.             activedlg->Handle=hwnd;
  952.             item=activedlg->Items;
  953.             while (item)
  954.             {    item->init();
  955.                 item=item->next();
  956.             }
  957.             activedlg->start();
  958.             // put dialog into dialog chain
  959.             activedlg->Next=dlgs;
  960.             dlgs=activedlg;
  961.             activedlg=0; // activedlg unusable
  962.             break;
  963.         case WM_CHAR :
  964.             if (dlg->key(SHORT1FROMMP(mp1),SHORT1FROMMP(mp2),
  965.                 SHORT2FROMMP(mp2))) break;
  966.             goto def;
  967.         case WM_HELP :
  968.             if (dlg->H) dlg->H->display(dlg->Hid);
  969.             break;
  970.         case WM_CONTROL :
  971.             result=dlg->Result=(SHORT1FROMMP(mp1));
  972.             item=dlg->Items;
  973.             while (item)
  974.             {    if (item->id()==result)
  975.                 {    item->command(mp1,mp2);
  976.                     return 0;
  977.                 }
  978.                 item=item->next();
  979.             }
  980.             break;
  981.         case WM_DESTROY :
  982.             result=-1;
  983.             goto finish;
  984.         case WM_COMMAND :
  985.             result=dlg->Result=(SHORT1FROMMP(mp1));
  986.             item=dlg->Items;
  987.             while (item)
  988.             {    if (item->id()==result)
  989.                 {    item->command(mp1,mp2);
  990.                     return 0;
  991.                 }
  992.                 item=item->next();
  993.             }
  994.             if (dlg->handler(result))
  995.             {   finish :
  996.                 item=dlg->Items;
  997.                 while (item)
  998.                 {    item->exit();
  999.                     item=item->next();
  1000.                 }
  1001.                 dlg->stop();
  1002.                 // remove dialog from dialog chain
  1003.                 if (dlgs==dlg) dlgs=dlg->Next;
  1004.                 else
  1005.                 {    dlg1=dlgs;
  1006.                     while (dlg1)
  1007.                     {    if (dlg1->Next==dlg) break;
  1008.                         dlg1=dlg1->Next;
  1009.                     }
  1010.                     if (dlg1) dlg1->Next=dlg->Next;
  1011.                 }
  1012.                 // close dialog
  1013.                 WinDismissDlg(hwnd,SHORT1FROMMP(mp1));
  1014.             }
  1015.             break;
  1016.         default :
  1017.             def: return WinDefDlgProc(hwnd,msg,mp1,mp2);
  1018.     }
  1019.     return 0;
  1020. }
  1021.  
  1022. void Dialog::init (Window &window, int id)
  1023. {    W=&window;
  1024.     Id=id;
  1025.     Items=0;
  1026. }
  1027.  
  1028. Dialog::Dialog (Window &window, int id, Help &h, int hid) : S()
  1029. {    init(window,id);
  1030.     H=&h; Hid=hid; Next=0;
  1031. }
  1032.  
  1033. Dialog::Dialog (Window &window, int id) : S()
  1034. {    init(window,id);
  1035.     H=0; Next=0;
  1036. }
  1037.  
  1038. Dialogitem *Dialog::entry (Dialogitem *item)
  1039. {    Dialogitem *note=Items;
  1040.     Items=item;
  1041.     return note;
  1042. }
  1043.  
  1044. void Dialog::carryout ()
  1045. {   activedlg=this;
  1046.     Handle=WinDlgBox(HWND_DESKTOP,W->handle(),dialogproc,
  1047.         (HMODULE)0,Id,NULL);
  1048. }
  1049.  
  1050. void Dialog::show ()
  1051. {   activedlg=this;
  1052.     Handle=WinLoadDlg(HWND_DESKTOP,W->handle(),dialogproc,
  1053.         (HMODULE)0,Id,NULL);
  1054. }
  1055.  
  1056. char *Dialog::gettext (int id, char *text, long size)
  1057. {   HWND handle=WinWindowFromID(Handle,id);
  1058.     WinQueryWindowText(handle,size,text);
  1059.     return text;
  1060. }
  1061.  
  1062. char *Dialog::gettext (int id)
  1063. {   HWND handle=WinWindowFromID(Handle,id);
  1064.     WinQueryWindowText(handle,S.size(),(PSZ)S.text());
  1065.     return S;
  1066. }
  1067.  
  1068. void Dialog::settext (int id, char *text)
  1069. {    HWND handle=WinWindowFromID(Handle,id);
  1070.     WinSetWindowText(handle,text);
  1071. }
  1072.  
  1073. MRESULT Dialog::message (int id, int msg,
  1074.     Parameter mp1, Parameter mp2)
  1075. {    HWND h;
  1076.     h=WinWindowFromID(Handle,id);
  1077.     return WinSendMsg(h,msg,mp1,mp2);
  1078. }
  1079.  
  1080. //*************** Dialog Items ******************
  1081.  
  1082. Dialogitem::Dialogitem (int id, Dialog &dialog)
  1083. {    Id=id;
  1084.     D=&dialog;
  1085.     Next=dialog.entry(this);
  1086. }
  1087.  
  1088. void StringItem::init ()
  1089. {   int size=strlen(S)+1;
  1090.     if (Length>size) size=Length;
  1091.     limit(size);
  1092.     D->settext(Id,S);
  1093.     D->message(Id,EM_SETREADONLY,Readonly);
  1094. }
  1095.  
  1096. void StringItem::exit ()
  1097. {    S.copy(D->gettext(Id));
  1098. }
  1099.  
  1100. void StringItem::limit (int length)
  1101. {    D->message(Id,EM_SETTEXTLIMIT,Parameter(length));
  1102. }
  1103.  
  1104. void CheckItem::init ()
  1105. {   D->message(Id,BM_SETCHECK,F);
  1106. }
  1107.  
  1108. void CheckItem::exit ()
  1109. {    F=(long)D->message(Id,BM_QUERYCHECK);
  1110. }
  1111.  
  1112. void RadioItem::init ()
  1113. {   D->message(Ids[I],BM_CLICK,1);
  1114. }
  1115.  
  1116. void RadioItem::exit ()
  1117. {    int i;
  1118.     for (i=0; i<N; i++)
  1119.     {    if (D->message(Ids[i],BM_SETCHECK))
  1120.         {    I=i; return;
  1121.         }
  1122.     }
  1123. }
  1124.  
  1125. void DoubleItem::init ()
  1126. {    sprintf(S,"%-0.10g",X);
  1127.     D->settext(Id,S);
  1128.     D->message(Id,EM_SETREADONLY,Readonly);
  1129. }
  1130.  
  1131. void DoubleItem::exit ()
  1132. {     S.copy(D->gettext(Id),64);
  1133.     sscanf(S,"%lg",&X);
  1134. }
  1135.  
  1136. void LongItem::init ()
  1137. {    sprintf(S,"%-ld",N);
  1138.     D->settext(Id,S);
  1139.     D->message(Id,EM_SETREADONLY,Readonly);
  1140. }
  1141.  
  1142. void LongItem::exit ()
  1143. {     S.copy(D->gettext(Id),64);
  1144.     sscanf(S,"%ld",&N);
  1145. }
  1146.  
  1147. void SpinItem::init ()
  1148. {    D->message(Id,SPBM_SETLIMITS,Upper,Lower);
  1149.     D->message(Id,SPBM_SETCURRENTVALUE,N);
  1150. }
  1151.  
  1152. void SpinItem::exit ()
  1153. {    D->message(Id,SPBM_QUERYVALUE,&N,Parameter(0,SPBQ_ALWAYSUPDATE));
  1154. }
  1155.  
  1156. void SliderItem::init ()
  1157. {    D->message(Id,SLM_SETSLIDERINFO,
  1158.         Parameter(SMA_SLIDERARMPOSITION,SMA_INCREMENTVALUE),
  1159.         Parameter(N));
  1160. }
  1161.  
  1162. void SliderItem::exit ()
  1163. {    N=(long)D->message(Id,SLM_QUERYSLIDERINFO,
  1164.         Parameter(SMA_SLIDERARMPOSITION,SMA_INCREMENTVALUE));
  1165. }
  1166.  
  1167. void SliderItem::tick (int n, int size)
  1168. {    D->message(Id,SLM_SETTICKSIZE,Parameter(n,size));
  1169. }
  1170.  
  1171. void SliderItem::label (int n, char *text)
  1172. {    D->message(Id,SLM_SETSCALETEXT,Parameter(n),Parameter(text));
  1173. }
  1174.  
  1175. void ValuesetItem::select (int row, int col)
  1176. {    D->message(Id,VM_SELECTITEM,Parameter(row,col));
  1177. }
  1178.  
  1179. void ValuesetItem::setbitmap (int row, int col, Bitmap &b)
  1180. {    D->message(Id,VM_SETITEMATTR,Parameter(row,col),
  1181.         Parameter(VIA_BITMAP,1));
  1182.     D->message(Id,VM_SETITEM,Parameter(row,col),
  1183.         Parameter((long)b.handle()));
  1184. }
  1185.  
  1186. void ValuesetItem::setcolor (int row, int col, long color)
  1187. {    D->message(Id,VM_SETITEMATTR,Parameter(row,col),
  1188.         Parameter(VIA_RGB,1));
  1189.     WindowPS ps(*D->w());
  1190.     color=GpiQueryRGBColor(ps.handle(),0,color);
  1191.     D->message(Id,VM_SETITEM,Parameter(row,col),
  1192.         Parameter((long)color));
  1193. }
  1194.  
  1195. void ValuesetItem::exit ()
  1196. {    Parameter p(D->message(Id,VM_QUERYSELECTEDITEM,0));
  1197.     Col=p.higher(); Row=p.lower();
  1198. }
  1199.  
  1200. void ValuesetItem::command (Parameter mp1, Parameter mp2)
  1201. {    if (mp1.higher()==VN_SELECT)
  1202.     {    Row=mp2.lower(); Col=mp2.higher();
  1203.         notify();
  1204.     }
  1205. }
  1206.  
  1207. void ListItem::insert (char *text)
  1208. {    D->message(Id,LM_INSERTITEM,Parameter(LIT_END),Parameter(text));
  1209. }
  1210.  
  1211. void ListItem::select (int sel)
  1212. {    D->message(Id,LM_SELECTITEM,Parameter(sel),Parameter(1));
  1213.     Selection=sel;
  1214. }
  1215.  
  1216. void ListItem::exit ()
  1217. {    Selection=Parameter(D->message(Id,LM_QUERYSELECTION)).lower();
  1218. }
  1219.  
  1220. void ListItem::command (Parameter mp1, Parameter mp2)
  1221. {    if (mp1.higher()==LN_ENTER)
  1222.     {   Selection=Parameter(D->message(Id,LM_QUERYSELECTION)).lower();
  1223.         notify();
  1224.     }
  1225. }
  1226.  
  1227. void MultilineItem::init ()
  1228. {    limit(S.size());
  1229.     D->settext(Id,S);
  1230.     D->message(Id,MLM_SETREADONLY,Readonly);
  1231. }
  1232.  
  1233. void MultilineItem::limit (int length)
  1234. {    D->message(Id,MLM_SETTEXTLIMIT,Parameter(length));
  1235. }
  1236.  
  1237. void MultilineItem::exit ()
  1238. {    D->gettext(Id,S,S.size());
  1239. }
  1240.  
  1241. //******************* File Selector ********************
  1242.  
  1243. FileSelector::FileSelector (Window &window,
  1244.         char *filter, int saving,
  1245.         char *title, char *ok) : Filter(filter),Title(title)
  1246.  
  1247. {    memset(&Fd,0,sizeof(FILEDLG));
  1248.  
  1249.     Fd.cbSize=sizeof(FILEDLG);
  1250.     Fd.fl=FDS_CENTER|FDS_ENABLEFILELB
  1251.         |(saving?FDS_SAVEAS_DIALOG:FDS_OPEN_DIALOG);
  1252.     Fd.pszTitle=(char *)Title;
  1253.     if (!ok)
  1254.     {    if (saving) Ok.copy("Save");
  1255.  
  1256.         else Ok.copy("Load");
  1257.  
  1258.     }
  1259.  
  1260.     else Ok.copy(ok);
  1261.  
  1262.     Fd.pszOKButton=(char *)Ok;
  1263.  
  1264.     W=&window;
  1265.  
  1266. }
  1267.  
  1268.  
  1269. char *FileSelector::select ()
  1270.  
  1271. {   char *p=Filter.filename();
  1272.  
  1273.     String s(Fd.szFullFile,256);
  1274.  
  1275.     s.stripfilename();
  1276.  
  1277.     strcpy(Fd.szFullFile,s); strcat(Fd.szFullFile,p);
  1278.  
  1279.     Freturn=WinFileDlg(HWND_DESKTOP,W->handle(),&Fd);
  1280.  
  1281.     if (!Freturn || Fd.lReturn!=DID_OK) return 0;
  1282.     return Fd.szFullFile;
  1283.  
  1284. }
  1285.  
  1286. // ************ Font Selector *********
  1287.  
  1288. int FontSelector::select (Window &window)
  1289. {   HPS hps;
  1290.     hps=WinGetPS(window.handle());
  1291.     memset(&Fd,0,sizeof(FONTDLG));
  1292.     Fd.cbSize=sizeof(FONTDLG);
  1293.     Fd.hpsScreen=hps;
  1294.     Fd.pszFamilyname=Facename;
  1295.     Fd.usFamilyBufLen=Facename.size();
  1296.     Fd.fxPointSize=long(Pointsize*65536);
  1297.     Fd.fl=FNTS_CENTER;
  1298.     Fd.clrFore=CLR_BLACK;
  1299.     Fd.clrBack=CLR_WHITE;
  1300.     Fd.fAttrs.usCodePage=Codepage;
  1301.     Result=0;
  1302.     WinFontDlg(HWND_DESKTOP,window.handle(),&Fd);
  1303.     Result=(Fd.lReturn==DID_OK);
  1304.     WinReleasePS(hps);
  1305.     return Result;
  1306. }
  1307.  
  1308. // *************** handling fonts **************************
  1309.  
  1310. Fonts::Fonts (PS &ps)
  1311. {    Count=0;
  1312.     Count=GpiQueryFonts(ps.handle(),
  1313.         QF_PUBLIC,0,&Count,sizeof(FONTMETRICS),0);
  1314.     AllFonts=new FONTMETRICS[Count];
  1315.     GpiQueryFonts(ps.handle(),
  1316.         QF_PUBLIC,0,&Count,sizeof(FONTMETRICS),AllFonts);
  1317. }
  1318.  
  1319. Fonts::~Fonts ()
  1320. {    delete AllFonts;
  1321. }
  1322.  
  1323. Font::Font (FontSelector &fs)
  1324. {    memcpy(&Fat,fs.fat(),sizeof(FATTRS));
  1325.     PointSize=fs.fd()->fxPointSize/65536.0;
  1326.     NominalPointSize=fs.fd()->sNominalPointSize/10.0;
  1327. }
  1328.  
  1329. // ************ Profile ***************
  1330.  
  1331. void Profile::writestring (char *k, char *i)
  1332. {    PrfWriteProfileString(P,S,k,i);
  1333. }
  1334.  
  1335. void Profile::writedouble (char *k, double x)
  1336. {    PrfWriteProfileData(P,S,k,&x,sizeof(double));
  1337. }
  1338.  
  1339. void Profile::writelong (char *k, long x)
  1340. {    PrfWriteProfileData(P,S,k,&x,sizeof(long));
  1341. }
  1342.  
  1343. void Profile::writeint (char *k, int x)
  1344. {    PrfWriteProfileData(P,S,k,&x,sizeof(int));
  1345. }
  1346.  
  1347. char *Profile::readstring (char *k, char *d, long size)
  1348. {    H.copy(d,size);
  1349.     PrfQueryProfileString(P,S,k,(char *)H,(char *)H,size);
  1350.     return H;
  1351. }
  1352.  
  1353. double Profile::readdouble (char *k, double x)
  1354. {   double res;
  1355.     unsigned long size=sizeof(double);
  1356.     if (PrfQueryProfileData(P,S,k,&res,&size)) return res;
  1357.     else return x;
  1358. }
  1359.  
  1360. long Profile::readlong (char *k, long x)
  1361. {   long res;
  1362.     unsigned long size=sizeof(long);
  1363.     if (PrfQueryProfileData(P,S,k,&res,&size)) return res;
  1364.     else return x;
  1365. }
  1366.  
  1367. int Profile::readint (char *k, int x)
  1368. {   int res;
  1369.     unsigned long size=sizeof(int);
  1370.     if (PrfQueryProfileData(P,S,k,&res,&size)) return res;
  1371.     else return x;
  1372. }
  1373.  
  1374. // ********** Clipboard ***************
  1375.  
  1376. void Clipboard::copy (MetafilePS &meta)
  1377. {   meta.close();
  1378.     if (!WinOpenClipbrd(program.hab())) return;
  1379.     WinEmptyClipbrd(program.hab());
  1380.     WinSetClipbrdData(program.hab(),
  1381.         meta.metafilehandle(),CF_METAFILE,CFI_HANDLE);
  1382.     WinCloseClipbrd(program.hab());
  1383. }
  1384.  
  1385.