graph.pp 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. This file implements the win32 gui support for the graph unit
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit Graph;
  13. interface
  14. uses
  15. windows;
  16. {$i graphh.inc}
  17. var
  18. { this procedure allows to hook keyboard messages }
  19. charmessagehandler : WndProc;
  20. { this procedure allows to hook mouse messages }
  21. mousemessagehandler : WndProc;
  22. { this procedure allows to wm_command messages }
  23. commandmessagehandler : WndProc;
  24. NotifyMessageHandler : WndProc;
  25. OnGraphWindowCreation : procedure;
  26. GraphWindow,ParentWindow : HWnd;
  27. // this allows direct drawing to the window
  28. bitmapdc : hdc;
  29. windc : hdc;
  30. const
  31. { predefined window style }
  32. { we shouldn't set CS_DBLCLKS here }
  33. { because most dos applications }
  34. { handle double clicks on it's own }
  35. graphwindowstyle : DWord = cs_hRedraw or cs_vRedraw;
  36. windowtitle : pchar = 'Graph window application';
  37. menu : hmenu = 0;
  38. icon : hicon = 0;
  39. drawtoscreen : boolean = true;
  40. drawtobitmap : boolean = true;
  41. // the graph window can be a child window, this allows to add toolbars
  42. // to the main window
  43. UseChildWindow : boolean = false;
  44. // this allows to specify an offset for the child child window
  45. ChildOffset : rect = (left:0;top:0;right:0;bottom:0);
  46. CONST
  47. m640x200x16 = VGALo;
  48. m640x400x16 = VGAMed;
  49. m640x480x16 = VGAHi;
  50. { VESA Specific video modes. }
  51. m320x200x32k = $10D;
  52. m320x200x64k = $10E;
  53. m640x400x256 = $100;
  54. m640x480x256 = $101;
  55. m640x480x32k = $110;
  56. m640x480x64k = $111;
  57. m800x600x16 = $102;
  58. m800x600x256 = $103;
  59. m800x600x32k = $113;
  60. m800x600x64k = $114;
  61. m1024x768x16 = $104;
  62. m1024x768x256 = $105;
  63. m1024x768x32k = $116;
  64. m1024x768x64k = $117;
  65. m1280x1024x16 = $106;
  66. m1280x1024x256 = $107;
  67. m1280x1024x32k = $119;
  68. m1280x1024x64k = $11A;
  69. { some extra modes which applies only to GUI }
  70. mLargestWindow16 = $f0;
  71. mLargestWindow256 = $f1;
  72. mLargestWindow32k = $f2;
  73. mLargestWindow64k = $f3;
  74. mLargestWindow16M = $f4;
  75. mMaximizedWindow16 = $f5;
  76. mMaximizedWindow256 = $f6;
  77. mMaximizedWindow32k = $f7;
  78. mMaximizedWindow64k = $f8;
  79. mMaximizedWindow16M = $f9;
  80. implementation
  81. uses
  82. strings;
  83. {
  84. Remarks:
  85. Colors in 16 color mode:
  86. ------------------------
  87. - the behavior of xor/or/and put isn't 100%:
  88. it is done using the RGB color getting from windows
  89. instead of the palette index!
  90. - palette operations aren't supported
  91. To solve these drawbacks, setpalette must be implemented
  92. by exchanging the colors in the DCs, further GetPaletteEntry
  93. must be used when doing xor/or/and operations
  94. }
  95. const
  96. InternalDriverName = 'WIN32GUI';
  97. {$i graph.inc}
  98. { used to create a file containing all calls to WM_PAINT
  99. WARNING this probably creates HUGE files PM }
  100. { $define DEBUG_WM_PAINT}
  101. var
  102. savedscreen : hbitmap;
  103. graphrunning : boolean;
  104. graphdrawing : tcriticalsection;
  105. pens : array[0..15] of HPEN;
  106. {$ifdef DEBUG_WM_PAINT}
  107. graphdebug : text;
  108. const
  109. wm_paint_count : longint = 0;
  110. var
  111. {$endif DEBUG_WM_PAINT}
  112. oldbitmap : hgdiobj;
  113. pal : ^rgbrec;
  114. // SavePtr : pointer; { we don't use that pointer }
  115. MessageThreadHandle : Handle;
  116. MessageThreadID : DWord;
  117. function GetPaletteEntry(r,g,b : word) : word;
  118. var
  119. dist,i,index,currentdist : longint;
  120. begin
  121. dist:=$7fffffff;
  122. index:=0;
  123. for i:=0 to maxcolors do
  124. begin
  125. currentdist:=abs(r-pal[i].red)+abs(g-pal[i].green)+
  126. abs(b-pal[i].blue);
  127. if currentdist<dist then
  128. begin
  129. index:=i;
  130. dist:=currentdist;
  131. if dist=0 then
  132. break;
  133. end;
  134. end;
  135. GetPaletteEntry:=index;
  136. end;
  137. procedure PutPixel16Win32GUI(x,y : smallint;pixel : word);
  138. var
  139. c : colorref;
  140. begin
  141. x:=x+startxviewport;
  142. y:=y+startyviewport;
  143. { convert to absolute coordinates and then verify clipping...}
  144. if clippixels then
  145. begin
  146. if (x<startxviewport) or (x>(startxviewport+viewwidth)) or
  147. (y<StartyViewPort) or (y>(startyviewport+viewheight)) then
  148. exit;
  149. end;
  150. if graphrunning then
  151. begin
  152. c:=RGB(pal[pixel].red,pal[pixel].green,pal[pixel].blue);
  153. EnterCriticalSection(graphdrawing);
  154. if drawtobitmap then
  155. SetPixelV(bitmapdc,x,y,c);
  156. if drawtoscreen then
  157. SetPixelV(windc,x,y,c);
  158. LeaveCriticalSection(graphdrawing);
  159. end;
  160. end;
  161. function GetPixel16Win32GUI(x,y : smallint) : word;
  162. var
  163. c : COLORREF;
  164. begin
  165. x:=x+startxviewport;
  166. y:=y+startyviewport;
  167. { convert to absolute coordinates and then verify clipping...}
  168. if clippixels then
  169. begin
  170. if (x<startxviewport) or (x>(startxviewport+viewwidth)) or
  171. (y<StartyViewPort) or (y>(startyviewport+viewheight)) then
  172. exit;
  173. end;
  174. if graphrunning then
  175. begin
  176. EnterCriticalSection(graphdrawing);
  177. c:=Windows.GetPixel(bitmapdc,x,y);
  178. LeaveCriticalSection(graphdrawing);
  179. GetPixel16Win32GUI:=GetPaletteEntry(GetRValue(c),GetGValue(c),GetBValue(c));
  180. end
  181. else
  182. begin
  183. _graphresult:=grerror;
  184. exit;
  185. end;
  186. end;
  187. procedure DirectPutPixel16Win32GUI(x,y : smallint);
  188. var
  189. col : longint;
  190. c,c2 : COLORREF;
  191. begin
  192. if graphrunning then
  193. begin
  194. EnterCriticalSection(graphdrawing);
  195. col:=CurrentColor;
  196. case currentwritemode of
  197. XorPut:
  198. Begin
  199. c2:=Windows.GetPixel(windc,x,y);
  200. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) xor c2;
  201. if drawtobitmap then
  202. SetPixelV(bitmapdc,x,y,c);
  203. if drawtoscreen then
  204. SetPixelV(windc,x,y,c);
  205. End;
  206. AndPut:
  207. Begin
  208. c2:=Windows.GetPixel(windc,x,y);
  209. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) and c2;
  210. if drawtobitmap then
  211. SetPixelV(bitmapdc,x,y,c);
  212. if drawtoscreen then
  213. SetPixelV(windc,x,y,c);
  214. End;
  215. OrPut:
  216. Begin
  217. c2:=Windows.GetPixel(windc,x,y);
  218. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) or c2;
  219. if drawtobitmap then
  220. SetPixelV(bitmapdc,x,y,c);
  221. if drawtoscreen then
  222. SetPixelV(windc,x,y,c);
  223. End
  224. else
  225. Begin
  226. If CurrentWriteMode<>NotPut Then
  227. col:=CurrentColor
  228. Else col := Not(CurrentColor);
  229. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  230. if drawtobitmap then
  231. SetPixelV(bitmapdc,x,y,c);
  232. if drawtoscreen then
  233. SetPixelV(windc,x,y,c);
  234. End
  235. end;
  236. LeaveCriticalSection(graphdrawing);
  237. end;
  238. end;
  239. var
  240. bitmapfontverticalcache : array[0..255] of HBITMAP;
  241. bitmapfonthorizoncache : array[0..255] of HBITMAP;
  242. procedure OutTextXYWin32GUI(x,y : smallint;const TextString : string);
  243. type
  244. Tpoint = record
  245. X,Y: smallint;
  246. end;
  247. var
  248. i,j,k,c : longint;
  249. xpos,ypos : longint;
  250. counter : longint;
  251. cnt1,cnt2 : smallint;
  252. cnt3,cnt4 : smallint;
  253. charsize : word;
  254. WriteMode : word;
  255. curX2, curY2, xpos2, ypos2, x2, y2: graph_float;
  256. oldvalues : linesettingstype;
  257. fontbitmap : TBitmapChar;
  258. chr : char;
  259. curx2i,cury2i,
  260. xpos2i,ypos2i : longint;
  261. charbitmap,oldcharbitmap : HBITMAP;
  262. chardc : HDC;
  263. color : longint;
  264. brushwin,oldbrushwin,brushbitmap,oldbrushbitmap : HBRUSH;
  265. bitmaprgn,winrgn : HRGN;
  266. begin
  267. { save current write mode }
  268. WriteMode := CurrentWriteMode;
  269. CurrentWriteMode := NormalPut;
  270. GetTextPosition(xpos,ypos,textstring);
  271. X:=X-XPos; Y:=Y+YPos;
  272. XPos:=X; YPos:=Y;
  273. CharSize := CurrentTextInfo.Charsize;
  274. if Currenttextinfo.font=DefaultFont then
  275. begin
  276. if CurrentTextInfo.direction=HorizDir then
  277. { Horizontal direction }
  278. begin
  279. if (x>viewwidth) or (y>viewheight) or
  280. (x<0) or (y<0) then
  281. begin
  282. CurrentWriteMode:=WriteMode;
  283. exit;
  284. end;
  285. EnterCriticalSection(graphdrawing);
  286. c:=length(textstring);
  287. chardc:=CreateCompatibleDC(windc);
  288. if currentcolor<>white then
  289. begin
  290. color:=RGB(pal[currentcolor].red,pal[currentcolor].green,
  291. pal[currentcolor].blue);
  292. if drawtoscreen then
  293. begin
  294. brushwin:=CreateSolidBrush(color);
  295. oldbrushwin:=SelectObject(windc,brushwin);
  296. end;
  297. if drawtobitmap then
  298. begin
  299. brushbitmap:=CreateSolidBrush(color);
  300. oldbrushbitmap:=SelectObject(bitmapdc,brushbitmap);
  301. end;
  302. end;
  303. inc(x,startxviewport);
  304. inc(y,startyviewport);
  305. { let windows do the clipping }
  306. if drawtobitmap then
  307. begin
  308. bitmaprgn:=CreateRectRgn(startxviewport,startyviewport,
  309. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  310. SelectClipRgn(bitmapdc,bitmaprgn);
  311. end;
  312. if drawtoscreen then
  313. begin
  314. winrgn:=CreateRectRgn(startxviewport,startyviewport,
  315. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  316. SelectClipRgn(windc,winrgn);
  317. end;
  318. for i:=0 to c-1 do
  319. begin
  320. xpos:=x+(i*8)*Charsize;
  321. if bitmapfonthorizoncache[byte(textstring[i+1])]=0 then
  322. begin
  323. charbitmap:=CreateCompatibleBitmap(windc,8,8);
  324. if charbitmap=0 then
  325. writeln('Bitmap konnte nicht erzeugt werden!');
  326. oldcharbitmap:=SelectObject(chardc,charbitmap);
  327. Fontbitmap:=TBitmapChar(DefaultFontData[textstring[i+1]]);
  328. for j:=0 to 7 do
  329. for k:=0 to 7 do
  330. if Fontbitmap[j,k]<>0 then
  331. SetPixelV(chardc,k,j,$ffffff)
  332. else
  333. SetPixelV(chardc,k,j,0);
  334. bitmapfonthorizoncache[byte(textstring[i+1])]:=charbitmap;
  335. SelectObject(chardc,oldcharbitmap);
  336. end;
  337. oldcharbitmap:=SelectObject(chardc,bitmapfonthorizoncache[byte(textstring[i+1])]);
  338. if CharSize=1 then
  339. begin
  340. if currentcolor=white then
  341. begin
  342. if drawtoscreen then
  343. BitBlt(windc,xpos,y,8,8,chardc,0,0,SRCPAINT);
  344. if drawtobitmap then
  345. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,SRCPAINT);
  346. end
  347. else
  348. begin
  349. { could we do this with one pattern operation ?? }
  350. { we would need something like DSnaSPao }
  351. if drawtoscreen then
  352. begin
  353. // ROP $00220326=DSna
  354. BitBlt(windc,xpos,y,8,8,chardc,0,0,$00220326);
  355. // ROP $00EA02E9 = DPSao
  356. BitBlt(windc,xpos,y,8,8,chardc,0,0,$00EA02E9);
  357. end;
  358. if drawtobitmap then
  359. begin
  360. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,$00220326);
  361. BitBlt(bitmapdc,xpos,y,8,8,chardc,0,0,$00EA02E9);
  362. end;
  363. end;
  364. end
  365. else
  366. begin
  367. if currentcolor=white then
  368. begin
  369. if drawtoscreen then
  370. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  371. if drawtobitmap then
  372. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  373. end
  374. else
  375. begin
  376. { could we do this with one pattern operation ?? }
  377. { we would need something like DSnaSPao }
  378. if drawtoscreen then
  379. begin
  380. // ROP $00220326=DSna
  381. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  382. // ROP $00EA02E9 = DPSao
  383. StretchBlt(windc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  384. end;
  385. if drawtobitmap then
  386. begin
  387. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  388. StretchBlt(bitmapdc,xpos,y,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  389. end;
  390. end;
  391. end;
  392. SelectObject(chardc,oldcharbitmap);
  393. end;
  394. if currentcolor<>white then
  395. begin
  396. if drawtoscreen then
  397. begin
  398. SelectObject(windc,oldbrushwin);
  399. DeleteObject(brushwin);
  400. end;
  401. if drawtobitmap then
  402. begin
  403. SelectObject(bitmapdc,oldbrushbitmap);
  404. DeleteObject(brushbitmap);
  405. end;
  406. end;
  407. { release clip regions }
  408. if drawtobitmap then
  409. begin
  410. SelectClipRgn(bitmapdc,0);
  411. DeleteObject(bitmaprgn);
  412. end;
  413. if drawtoscreen then
  414. begin
  415. SelectClipRgn(windc,0);
  416. DeleteObject(winrgn);
  417. end;
  418. DeleteDC(chardc);
  419. LeaveCriticalSection(graphdrawing);
  420. end
  421. else
  422. { Vertical direction }
  423. begin
  424. if (x>viewwidth) or (y>viewheight) or
  425. (x<0) or (y<0) then
  426. begin
  427. CurrentWriteMode:=WriteMode;
  428. exit;
  429. end;
  430. EnterCriticalSection(graphdrawing);
  431. c:=length(textstring);
  432. chardc:=CreateCompatibleDC(windc);
  433. if currentcolor<>white then
  434. begin
  435. color:=RGB(pal[currentcolor].red,pal[currentcolor].green,
  436. pal[currentcolor].blue);
  437. if drawtoscreen then
  438. begin
  439. brushwin:=CreateSolidBrush(color);
  440. oldbrushwin:=SelectObject(windc,brushwin);
  441. end;
  442. if drawtobitmap then
  443. begin
  444. brushbitmap:=CreateSolidBrush(color);
  445. oldbrushbitmap:=SelectObject(bitmapdc,brushbitmap);
  446. end;
  447. end;
  448. inc(x,startxviewport);
  449. inc(y,startyviewport);
  450. { let windows do the clipping }
  451. if drawtoscreen then
  452. begin
  453. winrgn:=CreateRectRgn(startxviewport,startyviewport,
  454. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  455. SelectClipRgn(windc,winrgn);
  456. end;
  457. if drawtobitmap then
  458. begin
  459. bitmaprgn:=CreateRectRgn(startxviewport,startyviewport,
  460. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  461. SelectClipRgn(bitmapdc,bitmaprgn);
  462. end;
  463. for i:=0 to c-1 do
  464. begin
  465. ypos:=y+1-((i+1)*8)*CharSize;
  466. if bitmapfontverticalcache[byte(textstring[i+1])]=0 then
  467. begin
  468. charbitmap:=CreateCompatibleBitmap(windc,8,8);
  469. if charbitmap=0 then
  470. writeln('Bitmap konnte nicht erzeugt werden!');
  471. oldcharbitmap:=SelectObject(chardc,charbitmap);
  472. Fontbitmap:=TBitmapChar(DefaultFontData[textstring[i+1]]);
  473. for j:=0 to 7 do
  474. for k:=0 to 7 do
  475. if Fontbitmap[j,k]<>0 then
  476. SetPixelV(chardc,j,7-k,$ffffff)
  477. else
  478. SetPixelV(chardc,j,7-k,0);
  479. bitmapfontverticalcache[byte(textstring[i+1])]:=charbitmap;
  480. SelectObject(chardc,oldcharbitmap);
  481. end;
  482. oldcharbitmap:=SelectObject(chardc,bitmapfontverticalcache[byte(textstring[i+1])]);
  483. if CharSize=1 then
  484. begin
  485. if currentcolor=white then
  486. begin
  487. if drawtoscreen then
  488. BitBlt(windc,x,ypos,8,8,chardc,0,0,SRCPAINT);
  489. if drawtobitmap then
  490. BitBlt(bitmapdc,x,ypos,8,8,chardc,0,0,SRCPAINT);
  491. end
  492. else
  493. begin
  494. { could we do this with one pattern operation ?? }
  495. { we would need something like DSnaSPao }
  496. if drawtoscreen then
  497. begin
  498. // ROP $00220326=DSna
  499. BitBlt(windc,x,ypos,8,8,chardc,0,0,$00220326);
  500. // ROP $00EA02E9 = DPSao
  501. BitBlt(windc,x,ypos,8,8,chardc,0,0,$00EA02E9);
  502. end;
  503. if drawtobitmap then
  504. begin
  505. BitBlt(bitmapdc,x,ypos,8,8,chardc,0,0,$00220326);
  506. BitBlt(bitmapdc,x,ypos,8,8,chardc,0,0,$00EA02E9);
  507. end;
  508. end;
  509. end
  510. else
  511. begin
  512. if currentcolor=white then
  513. begin
  514. if drawtoscreen then
  515. StretchBlt(windc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  516. if drawtobitmap then
  517. StretchBlt(bitmapdc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,SRCPAINT);
  518. end
  519. else
  520. begin
  521. { could we do this with one pattern operation ?? }
  522. { we would need something like DSnaSPao }
  523. if drawtoscreen then
  524. begin
  525. // ROP $00220326=DSna
  526. StretchBlt(windc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  527. // ROP $00EA02E9 = DPSao
  528. StretchBlt(windc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  529. end;
  530. if drawtobitmap then
  531. begin
  532. StretchBlt(bitmapdc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00220326);
  533. StretchBlt(bitmapdc,x,ypos,8*charsize,8*charsize,chardc,0,0,8,8,$00EA02E9);
  534. end;
  535. end;
  536. end;
  537. SelectObject(chardc,oldcharbitmap);
  538. end;
  539. if currentcolor<>white then
  540. begin
  541. if drawtoscreen then
  542. begin
  543. SelectObject(windc,oldbrushwin);
  544. DeleteObject(brushwin);
  545. end;
  546. if drawtobitmap then
  547. begin
  548. SelectObject(bitmapdc,oldbrushbitmap);
  549. DeleteObject(brushbitmap);
  550. end;
  551. end;
  552. { release clip regions }
  553. if drawtoscreen then
  554. begin
  555. SelectClipRgn(windc,0);
  556. DeleteObject(winrgn);
  557. end;
  558. if drawtobitmap then
  559. begin
  560. SelectClipRgn(bitmapdc,0);
  561. DeleteObject(bitmaprgn);
  562. end;
  563. DeleteDC(chardc);
  564. LeaveCriticalSection(graphdrawing);
  565. end;
  566. end else
  567. { This is a stroked font which is already loaded into memory }
  568. begin
  569. getlinesettings(oldvalues);
  570. { reset line style to defaults }
  571. setlinestyle(solidln,oldvalues.pattern,normwidth);
  572. if Currenttextinfo.direction=vertdir then
  573. xpos:=xpos + Textheight(textstring);
  574. CurX2:=xpos; xpos2 := curX2; x2 := xpos2;
  575. CurY2:=ypos; ypos2 := curY2; y2 := ypos2;
  576. { x:=xpos; y:=ypos;}
  577. for i:=1 to length(textstring) do
  578. begin
  579. c:=byte(textstring[i]);
  580. { Stroke_Count[c] := }
  581. unpack( fonts[CurrentTextInfo.font].instr,
  582. fonts[CurrentTextInfo.font].Offsets[c], Strokes );
  583. counter:=0;
  584. while true do
  585. begin
  586. if CurrentTextInfo.direction=VertDir then
  587. begin
  588. xpos2:=x2-(Strokes[counter].Y*CurrentYRatio);
  589. ypos2:=y2-(Strokes[counter].X*CurrentXRatio);
  590. end
  591. else
  592. begin
  593. xpos2:=x2+(Strokes[counter].X*CurrentXRatio) ;
  594. ypos2:=y2-(Strokes[counter].Y*CurrentYRatio) ;
  595. end;
  596. case opcodes(Strokes[counter].opcode) of
  597. _END_OF_CHAR: break;
  598. _DO_SCAN: begin
  599. { Currently unsupported };
  600. end;
  601. _MOVE : Begin
  602. CurX2 := XPos2;
  603. CurY2 := YPos2;
  604. end;
  605. _DRAW: Begin
  606. curx2i:=trunc(CurX2);
  607. cury2i:=trunc(CurY2);
  608. xpos2i:=trunc(xpos2);
  609. ypos2i:=trunc(ypos2);
  610. { this optimization doesn't matter that much
  611. if (curx2i=xpos2i) then
  612. begin
  613. if (cury2i=ypos2i) then
  614. putpixel(curx2i,cury2i,currentcolor)
  615. else if (cury2i+1=ypos2i) or
  616. (cury2i=ypos2i+1) then
  617. begin
  618. putpixel(curx2i,cury2i,currentcolor);
  619. putpixel(curx2i,ypos2i,currentcolor);
  620. end
  621. else
  622. Line(curx2i,cury2i,xpos2i,ypos2i);
  623. end
  624. else if (cury2i=ypos2i) then
  625. begin
  626. if (curx2i+1=xpos2i) or
  627. (curx2i=xpos2i+1) then
  628. begin
  629. putpixel(curx2i,cury2i,currentcolor);
  630. putpixel(xpos2i,cury2i,currentcolor);
  631. end
  632. else
  633. Line(curx2i,cury2i,xpos2i,ypos2i);
  634. end
  635. else
  636. }
  637. Line(curx2i,cury2i,xpos2i,ypos2i);
  638. CurX2:=xpos2;
  639. CurY2:=ypos2;
  640. end;
  641. else
  642. Begin
  643. end;
  644. end;
  645. Inc(counter);
  646. end; { end while }
  647. if Currenttextinfo.direction=VertDir then
  648. y2:=y2-(byte(fonts[CurrenttextInfo.font].widths[c])*CurrentXRatio)
  649. else
  650. x2:=x2+(byte(fonts[Currenttextinfo.font].widths[c])*CurrentXRatio);
  651. end;
  652. setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
  653. end;
  654. { restore write mode }
  655. CurrentWriteMode := WriteMode;
  656. end;
  657. procedure HLine16Win32GUI(x,x2,y: smallint);
  658. var
  659. c,c2 : COLORREF;
  660. col,i : longint;
  661. oldpen,pen : HPEN;
  662. Begin
  663. if graphrunning then
  664. begin
  665. { must we swap the values? }
  666. if x>x2 then
  667. Begin
  668. x:=x xor x2;
  669. x2:=x xor x2;
  670. x:=x xor x2;
  671. end;
  672. if ClipPixels then
  673. begin
  674. if (x>ViewWidth) or (y<0) or (y>ViewHeight) or (x2<0) then
  675. exit;
  676. if x<0 then
  677. x:=0;
  678. if x2>ViewWidth then
  679. x2:=ViewWidth;
  680. end;
  681. X:=X+StartXViewPort;
  682. X2:=X2+StartXViewPort;
  683. Y:=Y+StartYViewPort;
  684. Case CurrentWriteMode of
  685. AndPut:
  686. Begin
  687. EnterCriticalSection(graphdrawing);
  688. col:=CurrentColor;
  689. for i:=x to x2 do
  690. begin
  691. c2:=Windows.GetPixel(windc,i,y);
  692. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) and c2;
  693. if drawtobitmap then
  694. SetPixelV(bitmapdc,i,y,c);
  695. if drawtoscreen then
  696. SetPixelV(windc,i,y,c);
  697. end;
  698. LeaveCriticalSection(graphdrawing);
  699. End;
  700. XorPut:
  701. Begin
  702. EnterCriticalSection(graphdrawing);
  703. col:=CurrentColor;
  704. for i:=x to x2 do
  705. begin
  706. c2:=Windows.GetPixel(windc,i,y);
  707. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) xor c2;
  708. if drawtobitmap then
  709. SetPixelV(bitmapdc,i,y,c);
  710. if drawtoscreen then
  711. SetPixelV(windc,i,y,c);
  712. end;
  713. LeaveCriticalSection(graphdrawing);
  714. End;
  715. OrPut:
  716. Begin
  717. EnterCriticalSection(graphdrawing);
  718. col:=CurrentColor;
  719. for i:=x to x2 do
  720. begin
  721. c2:=Windows.GetPixel(windc,i,y);
  722. c:=RGB(pal[col].red,pal[col].green,pal[col].blue) or c2;
  723. if drawtobitmap then
  724. SetPixelV(bitmapdc,i,y,c);
  725. if drawtoscreen then
  726. SetPixelV(windc,i,y,c);
  727. end;
  728. LeaveCriticalSection(graphdrawing);
  729. End
  730. Else
  731. Begin
  732. If CurrentWriteMode<>NotPut Then
  733. col:=CurrentColor
  734. Else col:=Not(CurrentColor);
  735. EnterCriticalSection(graphdrawing);
  736. if x2-x<=2 then
  737. begin
  738. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  739. for x := x to x2 do
  740. begin
  741. if drawtobitmap then
  742. SetPixelV(bitmapdc,x,y,c);
  743. if drawtoscreen then
  744. SetPixelV(windc,x,y,c);
  745. end;
  746. end
  747. else
  748. begin
  749. if (col>=0) and (col<=high(pens)) then
  750. begin
  751. if pens[col]=0 then
  752. begin
  753. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  754. pens[col]:=CreatePen(PS_SOLID,1,c);
  755. end;
  756. pen:=pens[col];
  757. end
  758. else
  759. begin
  760. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  761. pen:=CreatePen(PS_SOLID,1,c);
  762. end;
  763. if drawtobitmap then
  764. begin
  765. oldpen:=SelectObject(bitmapdc,pen);
  766. Windows.MoveToEx(bitmapdc,x,y,nil);
  767. Windows.LineTo(bitmapdc,x2+1,y);
  768. SelectObject(bitmapdc,oldpen);
  769. end;
  770. if drawtoscreen then
  771. begin
  772. oldpen:=SelectObject(windc,pen);
  773. Windows.MoveToEx(windc,x,y,nil);
  774. Windows.LineTo(windc,x2+1,y);
  775. SelectObject(windc,oldpen);
  776. end;
  777. if (col<0) or (col>high(pens)) then
  778. DeleteObject(pen);
  779. end;
  780. LeaveCriticalSection(graphdrawing);
  781. End;
  782. End;
  783. end;
  784. end;
  785. procedure VLine16Win32GUI(x,y,y2: smallint); {$ifndef fpc}far;{$endif fpc}
  786. var
  787. ytmp: smallint;
  788. col,c : longint;
  789. oldpen,pen : HPEN;
  790. Begin
  791. { must we swap the values? }
  792. if y >= y2 then
  793. Begin
  794. ytmp := y2;
  795. y2 := y;
  796. y:= ytmp;
  797. end;
  798. if ClipPixels then
  799. begin
  800. if (x>ViewWidth) or (x<0) or (y>ViewHeight) or (y2<0) then
  801. exit;
  802. if y<0 then
  803. y:=0;
  804. if y2>ViewHeight then
  805. y2:=ViewHeight;
  806. end;
  807. { First convert to global coordinates }
  808. X := X + StartXViewPort;
  809. Y2 := Y2 + StartYViewPort;
  810. Y := Y + StartYViewPort;
  811. if currentwritemode=normalput then
  812. begin
  813. col:=CurrentColor;
  814. EnterCriticalSection(graphdrawing);
  815. if y2-y<=2 then
  816. begin
  817. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  818. for y := y to y2 do
  819. begin
  820. if drawtobitmap then
  821. SetPixelV(bitmapdc,x,y,c);
  822. if drawtoscreen then
  823. SetPixelV(windc,x,y,c);
  824. end;
  825. end
  826. else
  827. begin
  828. if (col>=0) and (col<=high(pens)) then
  829. begin
  830. if pens[col]=0 then
  831. begin
  832. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  833. pens[col]:=CreatePen(PS_SOLID,1,c);
  834. end;
  835. pen:=pens[col];
  836. end
  837. else
  838. begin
  839. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  840. pen:=CreatePen(PS_SOLID,1,c);
  841. end;
  842. if drawtobitmap then
  843. begin
  844. oldpen:=SelectObject(bitmapdc,pen);
  845. Windows.MoveToEx(bitmapdc,x,y,nil);
  846. Windows.LineTo(bitmapdc,x,y2+1);
  847. SelectObject(bitmapdc,oldpen);
  848. end;
  849. if drawtoscreen then
  850. begin
  851. oldpen:=SelectObject(windc,pen);
  852. Windows.MoveToEx(windc,x,y,nil);
  853. Windows.LineTo(windc,x,y2+1);
  854. SelectObject(windc,oldpen);
  855. end;
  856. if (col<0) or (col>high(pens)) then
  857. DeleteObject(pen);
  858. end;
  859. LeaveCriticalSection(graphdrawing);
  860. end
  861. else
  862. for y := y to y2 do Directputpixel(x,y)
  863. End;
  864. procedure Circle16Win32GUI(X, Y: smallint; Radius:Word);
  865. var
  866. bitmaprgn,winrgn : HRGN;
  867. col,c : longint;
  868. oldpen,pen : HPEN;
  869. OriginalArcInfo: ArcCoordsType;
  870. OldWriteMode: word;
  871. begin
  872. if (Radius = 0) then
  873. Exit;
  874. if (Radius = 1) then
  875. begin
  876. { only normal put mode is supported by a call to PutPixel }
  877. PutPixel(X, Y, CurrentColor);
  878. Exit;
  879. end;
  880. if (Radius = 2) then
  881. begin
  882. { only normal put mode is supported by a call to PutPixel }
  883. PutPixel(X-1, Y, CurrentColor);
  884. PutPixel(X+1, Y, CurrentColor);
  885. PutPixel(X, Y-1, CurrentColor);
  886. PutPixel(X, Y+1, CurrentColor);
  887. Exit;
  888. end;
  889. if LineInfo.Thickness = Normwidth then
  890. begin
  891. EnterCriticalSection(graphdrawing);
  892. { let windows do the clipping }
  893. if drawtobitmap then
  894. begin
  895. bitmaprgn:=CreateRectRgn(startxviewport,startyviewport,
  896. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  897. SelectClipRgn(bitmapdc,bitmaprgn);
  898. end;
  899. if drawtoscreen then
  900. begin
  901. winrgn:=CreateRectRgn(startxviewport,startyviewport,
  902. startxviewport+viewwidth+1,startyviewport+viewheight+1);
  903. SelectClipRgn(windc,winrgn);
  904. end;
  905. inc(x,StartXViewPort);
  906. inc(y,StartYViewPort);
  907. col:=CurrentColor;
  908. if (col>=0) and (col<=high(pens)) then
  909. begin
  910. if pens[col]=0 then
  911. begin
  912. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  913. pens[col]:=CreatePen(PS_SOLID,1,c);
  914. end;
  915. pen:=pens[col];
  916. end
  917. else
  918. begin
  919. c:=RGB(pal[col].red,pal[col].green,pal[col].blue);
  920. pen:=CreatePen(PS_SOLID,1,c);
  921. end;
  922. if drawtobitmap then
  923. begin
  924. oldpen:=SelectObject(bitmapdc,pen);
  925. windows.arc(bitmapdc,x-radius,y-radius,x+radius,y+radius,
  926. x,y-radius,x,y-radius);
  927. SelectObject(bitmapdc,oldpen);
  928. end;
  929. if drawtoscreen then
  930. begin
  931. oldpen:=SelectObject(windc,pen);
  932. windows.arc(windc,x-radius,y-radius,x+radius,y+radius,
  933. x,y-radius,x,y-radius);
  934. SelectObject(windc,oldpen);
  935. end;
  936. if (col<0) or (col>high(pens)) then
  937. DeleteObject(pen);
  938. { release clip regions }
  939. if drawtoscreen then
  940. begin
  941. SelectClipRgn(windc,0);
  942. DeleteObject(winrgn);
  943. end;
  944. if drawtobitmap then
  945. begin
  946. SelectClipRgn(bitmapdc,0);
  947. DeleteObject(bitmaprgn);
  948. end;
  949. LeaveCriticalSection(graphdrawing);
  950. end
  951. else
  952. begin
  953. { save state of arc information }
  954. { because it is not needed for }
  955. { a circle call. }
  956. move(ArcCall,OriginalArcInfo, sizeof(ArcCall));
  957. InternalEllipse(X,Y,Radius,Radius,0,360,{$ifdef fpc}@{$endif}DummyPatternLine);
  958. { restore arc information }
  959. move(OriginalArcInfo, ArcCall,sizeof(ArcCall));
  960. end;
  961. end;
  962. {
  963. Procedure PutImageWin32GUI(X,Y: smallint; var Bitmap; BitBlt: Word); {$ifndef fpc}far;{$endif fpc}
  964. type
  965. pt = array[0..$fffffff] of word;
  966. ptw = array[0..2] of longint;
  967. var
  968. k: longint;
  969. oldCurrentColor: word;
  970. oldCurrentWriteMode, i, j, y1, x1, deltaX, deltaX1, deltaY: smallint;
  971. Begin
  972. {$ifdef logging}
  973. LogLn('putImage at ('+strf(x)+','+strf(y)+') with width '+strf(ptw(Bitmap)[0])+
  974. ' and height '+strf(ptw(Bitmap)[1]));
  975. deltaY := 0;
  976. {$endif logging}
  977. inc(x,startXViewPort);
  978. inc(y,startYViewPort);
  979. x1 := ptw(Bitmap)[0]+x; { get width and adjust end coordinate accordingly }
  980. y1 := ptw(Bitmap)[1]+y; { get height and adjust end coordinate accordingly }
  981. deltaX := 0;
  982. deltaX1 := 0;
  983. k := 3 * sizeOf(Longint) div sizeOf(Word); { Three reserved longs at start of bitmap }
  984. { check which part of the image is in the viewport }
  985. if clipPixels then
  986. begin
  987. if y < startYViewPort then
  988. begin
  989. deltaY := startYViewPort - y;
  990. inc(k,(x1-x+1)*deltaY);
  991. y := startYViewPort;
  992. end;
  993. if y1 > startYViewPort+viewHeight then
  994. y1 := startYViewPort+viewHeight;
  995. if x < startXViewPort then
  996. begin
  997. deltaX := startXViewPort-x;
  998. x := startXViewPort;
  999. end;
  1000. if x1 > startXViewPort + viewWidth then
  1001. begin
  1002. deltaX1 := x1 - (startXViewPort + viewWidth);
  1003. x1 := startXViewPort + viewWidth;
  1004. end;
  1005. end;
  1006. {$ifdef logging}
  1007. LogLn('deltax: '+strf(deltax)+', deltax1: '+strf(deltax1)+',deltay: '+strf(deltay));
  1008. {$endif logging}
  1009. case bitBlt of
  1010. end;
  1011. oldCurrentColor := currentColor;
  1012. oldCurrentWriteMode := currentWriteMode;
  1013. currentWriteMode := bitBlt;
  1014. for j:=Y to Y1 do
  1015. Begin
  1016. inc(k,deltaX);
  1017. for i:=X to X1 do
  1018. begin
  1019. currentColor := pt(bitmap)[k];
  1020. directPutPixel(i,j);
  1021. inc(k);
  1022. end;
  1023. inc(k,deltaX1);
  1024. end;
  1025. currentWriteMode := oldCurrentWriteMode;
  1026. currentColor := oldCurrentColor;
  1027. end;
  1028. }
  1029. procedure SetRGBPaletteWin32GUI(colorNum,redValue,greenvalue,
  1030. bluevalue : smallint);
  1031. begin
  1032. if directcolor or (colornum<0) or (colornum>=maxcolor) then
  1033. begin
  1034. _graphresult:=grerror;
  1035. exit;
  1036. end;
  1037. pal[colorNum].red:=redValue;
  1038. pal[colorNum].green:=greenValue;
  1039. pal[colorNum].blue:=blueValue;
  1040. if (colorNum>=0) and (colorNum<=high(pens)) and (pens[colorNum]<>0) then
  1041. begin
  1042. DeleteObject(pens[colorNum]);
  1043. pens[colorNum]:=0;
  1044. end;
  1045. end;
  1046. procedure GetRGBPaletteWin32GUI(colorNum : smallint;
  1047. var redValue,greenvalue,bluevalue : smallint);
  1048. begin
  1049. if directcolor or (colornum<0) or (colornum>=maxcolor) then
  1050. begin
  1051. _graphresult:=grerror;
  1052. exit;
  1053. end;
  1054. redValue:=pal[colorNum].red;
  1055. greenValue:=pal[colorNum].green;
  1056. blueValue:=pal[colorNum].blue;
  1057. end;
  1058. procedure savestate;
  1059. begin
  1060. end;
  1061. procedure restorestate;
  1062. begin
  1063. end;
  1064. function WindowProcGraph(Window: HWnd; AMessage:UInt; WParam : WParam;
  1065. LParam: LParam): Longint; stdcall;
  1066. var
  1067. dc : hdc;
  1068. ps : paintstruct;
  1069. r : rect;
  1070. oldbrush : hbrush;
  1071. oldpen : hpen;
  1072. i : longint;
  1073. begin
  1074. WindowProcGraph := 0;
  1075. case AMessage of
  1076. wm_lbuttondown,
  1077. wm_rbuttondown,
  1078. wm_mbuttondown,
  1079. wm_lbuttonup,
  1080. wm_rbuttonup,
  1081. wm_mbuttonup,
  1082. wm_lbuttondblclk,
  1083. wm_rbuttondblclk,
  1084. wm_mbuttondblclk:
  1085. {
  1086. This leads to problem, i.e. the menu etc doesn't work any longer
  1087. wm_nclbuttondown,
  1088. wm_ncrbuttondown,
  1089. wm_ncmbuttondown,
  1090. wm_nclbuttonup,
  1091. wm_ncrbuttonup,
  1092. wm_ncmbuttonup,
  1093. wm_nclbuttondblclk,
  1094. wm_ncrbuttondblclk,
  1095. wm_ncmbuttondblclk:
  1096. }
  1097. begin
  1098. if assigned(mousemessagehandler) then
  1099. WindowProcGraph:=mousemessagehandler(window,amessage,wparam,lparam);
  1100. end;
  1101. wm_notify:
  1102. begin
  1103. if assigned(notifymessagehandler) then
  1104. WindowProcGraph:=notifymessagehandler(window,amessage,wparam,lparam);
  1105. end;
  1106. wm_command:
  1107. if assigned(commandmessagehandler) then
  1108. WindowProcGraph:=commandmessagehandler(window,amessage,wparam,lparam);
  1109. wm_keydown,
  1110. wm_keyup,
  1111. wm_char:
  1112. begin
  1113. if assigned(charmessagehandler) then
  1114. WindowProcGraph:=charmessagehandler(window,amessage,wparam,lparam);
  1115. end;
  1116. wm_paint:
  1117. begin
  1118. {$ifdef DEBUG_WM_PAINT}
  1119. inc(wm_paint_count);
  1120. {$endif DEBUG_WM_PAINT}
  1121. {$ifdef DEBUGCHILDS}
  1122. writeln('Start child painting');
  1123. {$endif DEBUGCHILDS}
  1124. if not GetUpdateRect(Window,@r,false) then
  1125. exit;
  1126. EnterCriticalSection(graphdrawing);
  1127. graphrunning:=true;
  1128. dc:=BeginPaint(Window,@ps);
  1129. {$ifdef DEBUG_WM_PAINT}
  1130. Writeln(graphdebug,'WM_PAINT in ((',r.left,',',r.top,
  1131. '),(',r.right,',',r.bottom,'))');
  1132. {$endif def DEBUG_WM_PAINT}
  1133. if graphrunning then
  1134. {BitBlt(dc,0,0,maxx+1,maxy+1,bitmapdc,0,0,SRCCOPY);}
  1135. BitBlt(dc,r.left,r.top,r.right-r.left+1,r.bottom-r.top+1,bitmapdc,r.left,r.top,SRCCOPY);
  1136. EndPaint(Window,ps);
  1137. LeaveCriticalSection(graphdrawing);
  1138. Exit;
  1139. end;
  1140. wm_create:
  1141. begin
  1142. {$ifdef DEBUG_WM_PAINT}
  1143. assign(graphdebug,'wingraph.log');
  1144. rewrite(graphdebug);
  1145. {$endif DEBUG_WM_PAINT}
  1146. {$ifdef DEBUGCHILDS}
  1147. writeln('Creating window (HWND: ',window,')... ');
  1148. {$endif DEBUGCHILDS}
  1149. GraphWindow:=window;
  1150. EnterCriticalSection(graphdrawing);
  1151. dc:=GetDC(window);
  1152. {$ifdef DEBUGCHILDS}
  1153. writeln('Window DC: ',dc);
  1154. {$endif DEBUGCHILDS}
  1155. bitmapdc:=CreateCompatibleDC(dc);
  1156. savedscreen:=CreateCompatibleBitmap(dc,maxx+1,maxy+1);
  1157. ReleaseDC(window,dc);
  1158. oldbitmap:=SelectObject(bitmapdc,savedscreen);
  1159. windc:=GetDC(window);
  1160. // clear everything
  1161. oldpen:=SelectObject(bitmapdc,GetStockObject(BLACK_PEN));
  1162. oldbrush:=SelectObject(bitmapdc,GetStockObject(BLACK_BRUSH));
  1163. Windows.Rectangle(bitmapdc,0,0,maxx,maxy);
  1164. SelectObject(bitmapdc,oldpen);
  1165. SelectObject(bitmapdc,oldbrush);
  1166. // ... the window too
  1167. oldpen:=SelectObject(windc,GetStockObject(BLACK_PEN));
  1168. oldbrush:=SelectObject(windc,GetStockObject(BLACK_BRUSH));
  1169. Windows.Rectangle(windc,0,0,maxx,maxy);
  1170. SelectObject(windc,oldpen);
  1171. SelectObject(windc,oldbrush);
  1172. // clear font cache
  1173. fillchar(bitmapfonthorizoncache,sizeof(bitmapfonthorizoncache),0);
  1174. fillchar(bitmapfontverticalcache,sizeof(bitmapfontverticalcache),0);
  1175. // clear predefined pens
  1176. fillchar(pens,sizeof(pens),0);
  1177. if assigned(OnGraphWindowCreation) then
  1178. OnGraphWindowCreation;
  1179. LeaveCriticalSection(graphdrawing);
  1180. {$ifdef DEBUGCHILDS}
  1181. writeln('done');
  1182. GetClientRect(window,@r);
  1183. writeln('Window size: ',r.right,',',r.bottom);
  1184. {$endif DEBUGCHILDS}
  1185. end;
  1186. wm_Destroy:
  1187. begin
  1188. EnterCriticalSection(graphdrawing);
  1189. graphrunning:=false;
  1190. ReleaseDC(GraphWindow,windc);
  1191. SelectObject(bitmapdc,oldbitmap);
  1192. DeleteObject(savedscreen);
  1193. DeleteDC(bitmapdc);
  1194. // release font cache
  1195. for i:=0 to 255 do
  1196. if bitmapfonthorizoncache[i]<>0 then
  1197. DeleteObject(bitmapfonthorizoncache[i]);
  1198. for i:=0 to 255 do
  1199. if bitmapfontverticalcache[i]<>0 then
  1200. DeleteObject(bitmapfontverticalcache[i]);
  1201. for i:=0 to high(pens) do
  1202. if pens[i]<>0 then
  1203. DeleteObject(pens[i]);
  1204. LeaveCriticalSection(graphdrawing);
  1205. {$ifdef DEBUG_WM_PAINT}
  1206. close(graphdebug);
  1207. {$endif DEBUG_WM_PAINT}
  1208. PostQuitMessage(0);
  1209. Exit;
  1210. end
  1211. else
  1212. WindowProcGraph := DefWindowProc(Window, AMessage, WParam, LParam);
  1213. end;
  1214. end;
  1215. function WindowProcParent(Window: HWnd; AMessage:UInt; WParam : WParam;
  1216. LParam: LParam): Longint; stdcall;
  1217. begin
  1218. WindowProcParent := 0;
  1219. case AMessage of
  1220. wm_keydown,
  1221. wm_keyup,
  1222. wm_char:
  1223. begin
  1224. if assigned(charmessagehandler) then
  1225. WindowProcParent:=charmessagehandler(window,amessage,wparam,lparam);
  1226. end;
  1227. wm_notify:
  1228. begin
  1229. if assigned(notifymessagehandler) then
  1230. WindowProcParent:=notifymessagehandler(window,amessage,wparam,lparam);
  1231. end;
  1232. wm_command:
  1233. if assigned(commandmessagehandler) then
  1234. WindowProcParent:=commandmessagehandler(window,amessage,wparam,lparam);
  1235. else
  1236. WindowProcParent := DefWindowProc(Window, AMessage, WParam, LParam);
  1237. end;
  1238. end;
  1239. function WinRegister: Boolean;
  1240. var
  1241. WindowClass: WndClass;
  1242. begin
  1243. WindowClass.Style := graphwindowstyle;
  1244. WindowClass.lpfnWndProc := WndProc(@WindowProcGraph);
  1245. WindowClass.cbClsExtra := 0;
  1246. WindowClass.cbWndExtra := 0;
  1247. WindowClass.hInstance := system.MainInstance;
  1248. if icon<>0 then
  1249. WindowClass.hIcon := icon
  1250. else
  1251. WindowClass.hIcon := LoadIcon(0, idi_Application);
  1252. WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  1253. WindowClass.hbrBackground := GetStockObject(BLACK_BRUSH);
  1254. if menu<>0 then
  1255. WindowClass.lpszMenuName := MAKEINTRESOURCE(menu)
  1256. else
  1257. WindowClass.lpszMenuName := nil;
  1258. WindowClass.lpszClassName := 'FPCGraphWindow';
  1259. winregister:=RegisterClass(WindowClass) <> 0;
  1260. end;
  1261. function WinRegisterWithChild: Boolean;
  1262. var
  1263. WindowClass: WndClass;
  1264. begin
  1265. WindowClass.Style := graphwindowstyle;
  1266. WindowClass.lpfnWndProc := WndProc(@WindowProcParent);
  1267. WindowClass.cbClsExtra := 0;
  1268. WindowClass.cbWndExtra := 0;
  1269. WindowClass.hInstance := system.MainInstance;
  1270. if icon<>0 then
  1271. WindowClass.hIcon := icon
  1272. else
  1273. WindowClass.hIcon := LoadIcon(0, idi_Application);
  1274. WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  1275. WindowClass.hbrBackground := GetStockObject(BLACK_BRUSH);
  1276. if menu<>0 then
  1277. WindowClass.lpszMenuName := MAKEINTRESOURCE(menu)
  1278. else
  1279. WindowClass.lpszMenuName := nil;
  1280. WindowClass.lpszClassName := 'FPCGraphWindowMain';
  1281. WinRegisterWithChild:=RegisterClass(WindowClass) <> 0;
  1282. {$ifdef DEBUGCHILDS}
  1283. writeln('Main window successfully registered: WinRegisterWithChild is ',WinRegisterWithChild);
  1284. {$endif DEBUGCHILDS}
  1285. if WinRegisterWithChild then
  1286. begin
  1287. WindowClass.Style := CS_HREDRAW or CS_VREDRAW;
  1288. WindowClass.lpfnWndProc := WndProc(@WindowProcGraph);
  1289. WindowClass.cbClsExtra := 0;
  1290. WindowClass.cbWndExtra := 0;
  1291. WindowClass.hInstance := system.MainInstance;
  1292. WindowClass.hIcon := 0;
  1293. WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  1294. WindowClass.hbrBackground := GetStockObject(BLACK_BRUSH);
  1295. WindowClass.lpszMenuName := nil;
  1296. WindowClass.lpszClassName := 'FPCGraphWindowChild';
  1297. WinRegisterWithChild:=RegisterClass(WindowClass)<>0;
  1298. {$ifdef DEBUGCHILDS}
  1299. writeln('Child window registered: WinRegisterWithChild is ',WinRegisterWithChild);
  1300. {$endif DEBUGCHILDS}
  1301. end;
  1302. end;
  1303. var
  1304. // here we can force the creation of a maximized window }
  1305. extrastyle : cardinal;
  1306. { Create the Window Class }
  1307. function WinCreate : HWnd;
  1308. var
  1309. hWindow: HWnd;
  1310. begin
  1311. WinCreate:=0;
  1312. if UseChildWindow then
  1313. begin
  1314. ParentWindow:=CreateWindow('FPCGraphWindowMain', windowtitle,
  1315. WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or extrastyle, longint(CW_USEDEFAULT), 0,
  1316. maxx+ChildOffset.Left+ChildOffset.Right+1+
  1317. 2*GetSystemMetrics(SM_CXFRAME),
  1318. maxy+ChildOffset.Top+ChildOffset.Bottom+1+
  1319. 2*GetSystemMetrics(SM_CYFRAME)+
  1320. GetSystemMetrics(SM_CYCAPTION),
  1321. 0, 0, system.MainInstance, nil);
  1322. if ParentWindow<>0 then
  1323. begin
  1324. ShowWindow(ParentWindow, SW_SHOW);
  1325. UpdateWindow(ParentWindow);
  1326. end
  1327. else
  1328. exit;
  1329. hWindow:=CreateWindow('FPCGraphWindowChild',nil,
  1330. WS_CHILD, ChildOffset.Left,ChildOffset.Top,
  1331. maxx+1,maxy+1,
  1332. ParentWindow, 0, system.MainInstance, nil);
  1333. if hwindow<>0 then
  1334. begin
  1335. ShowWindow(hwindow, SW_SHOW);
  1336. UpdateWindow(hwindow);
  1337. end
  1338. else
  1339. exit;
  1340. WinCreate:=hWindow;
  1341. end
  1342. else
  1343. begin
  1344. hWindow:=CreateWindow('FPCGraphWindow', windowtitle,
  1345. ws_OverlappedWindow or extrastyle, longint(CW_USEDEFAULT), 0,
  1346. maxx+1+2*GetSystemMetrics(SM_CXFRAME),
  1347. maxy+1+2*GetSystemMetrics(SM_CYFRAME)+
  1348. GetSystemMetrics(SM_CYCAPTION),
  1349. 0, 0, system.MainInstance, nil);
  1350. if hWindow <> 0 then
  1351. begin
  1352. ShowWindow(hWindow, SW_SHOW);
  1353. UpdateWindow(hWindow);
  1354. WinCreate:=hWindow;
  1355. end;
  1356. end;
  1357. end;
  1358. const
  1359. winregistered : boolean = false;
  1360. function MessageHandleThread(p : pointer) : DWord;StdCall;
  1361. var
  1362. AMessage: Msg;
  1363. begin
  1364. if not(winregistered) then
  1365. begin
  1366. if UseChildWindow then
  1367. begin
  1368. if not(WinRegisterWithChild) then
  1369. begin
  1370. MessageBox(0, 'Window registration failed', nil, mb_Ok);
  1371. ExitThread(1);
  1372. end;
  1373. end
  1374. else
  1375. begin
  1376. if not(WinRegister) then
  1377. begin
  1378. MessageBox(0, 'Window registration failed', nil, mb_Ok);
  1379. ExitThread(1);
  1380. end;
  1381. end;
  1382. winregistered:=true;
  1383. end;
  1384. GraphWindow:=WinCreate;
  1385. if longint(GraphWindow) = 0 then begin
  1386. MessageBox(0, 'Window creation failed', nil, mb_Ok);
  1387. ExitThread(1);
  1388. end;
  1389. while longint(GetMessage(@AMessage, 0, 0, 0))=longint(true) do
  1390. begin
  1391. TranslateMessage(AMessage);
  1392. DispatchMessage(AMessage);
  1393. end;
  1394. MessageHandleThread:=0;
  1395. end;
  1396. procedure InitWin32GUI16colors;
  1397. var
  1398. threadexitcode : longint;
  1399. begin
  1400. getmem(pal,sizeof(RGBrec)*maxcolor);
  1401. move(DefaultColors,pal^,sizeof(RGBrec)*maxcolor);
  1402. if (IntCurrentMode=mMaximizedWindow16) or
  1403. (IntCurrentMode=mMaximizedWindow256) or
  1404. (IntCurrentMode=mMaximizedWindow32k) or
  1405. (IntCurrentMode=mMaximizedWindow64k) or
  1406. (IntCurrentMode=mMaximizedWindow16M) then
  1407. extrastyle:=ws_maximize
  1408. else
  1409. extrastyle:=0;
  1410. { start graph subsystem }
  1411. InitializeCriticalSection(graphdrawing);
  1412. graphrunning:=false;
  1413. MessageThreadHandle:=CreateThread(nil,0,@MessageHandleThread,
  1414. nil,0,MessageThreadID);
  1415. repeat
  1416. GetExitCodeThread(MessageThreadHandle,@threadexitcode);
  1417. until graphrunning or (threadexitcode<>STILL_ACTIVE);
  1418. if threadexitcode<>STILL_ACTIVE then
  1419. _graphresult := grerror;
  1420. end;
  1421. procedure CloseGraph;
  1422. begin
  1423. If not isgraphmode then
  1424. begin
  1425. _graphresult := grnoinitgraph;
  1426. exit
  1427. end;
  1428. if UseChildWindow then
  1429. begin
  1430. { if the child window isn't destroyed }
  1431. { the main window can't be closed }
  1432. { I don't know any other way (FK) }
  1433. PostMessage(GraphWindow,wm_destroy,0,0);
  1434. PostMessage(ParentWindow,wm_destroy,0,0)
  1435. end
  1436. else
  1437. PostMessage(GraphWindow,wm_destroy,0,0);
  1438. PostThreadMessage(MessageThreadHandle,wm_quit,0,0);
  1439. WaitForSingleObject(MessageThreadHandle,Infinite);
  1440. CloseHandle(MessageThreadHandle);
  1441. DeleteCriticalSection(graphdrawing);
  1442. freemem(pal,sizeof(RGBrec)*maxcolor);
  1443. MessageThreadID := 0;
  1444. MessageThreadHandle := 0;
  1445. isgraphmode := false;
  1446. end;
  1447. procedure LineWin32GUI(X1, Y1, X2, Y2: smallint); {$ifndef fpc}far;{$endif fpc}
  1448. var X, Y : smallint;
  1449. deltax, deltay : smallint;
  1450. d, dinc1, dinc2: smallint;
  1451. xinc1 : smallint;
  1452. xinc2 : smallint;
  1453. yinc1 : smallint;
  1454. yinc2 : smallint;
  1455. i : smallint;
  1456. Flag : Boolean; { determines pixel direction in thick lines }
  1457. NumPixels : smallint;
  1458. PixelCount : smallint;
  1459. OldCurrentColor: Word;
  1460. swtmp : smallint;
  1461. TmpNumPixels : smallint;
  1462. col : longint;
  1463. pen,oldpen : hpen;
  1464. begin
  1465. if graphrunning then
  1466. begin
  1467. {******************************************}
  1468. { SOLID LINES }
  1469. {******************************************}
  1470. if lineinfo.LineStyle = SolidLn then
  1471. Begin
  1472. { Convert to global coordinates. }
  1473. x1 := x1 + StartXViewPort;
  1474. x2 := x2 + StartXViewPort;
  1475. y1 := y1 + StartYViewPort;
  1476. y2 := y2 + StartYViewPort;
  1477. { if fully clipped then exit... }
  1478. if ClipPixels then
  1479. begin
  1480. if LineClipped(x1,y1,x2,y2,StartXViewPort, StartYViewPort,
  1481. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  1482. exit;
  1483. If LineInfo.Thickness=NormWidth then
  1484. Begin
  1485. EnterCriticalSection(graphdrawing);
  1486. {
  1487. if currentwritemode<>normalput then
  1488. begin
  1489. case currentwritemode of
  1490. XORPut:
  1491. begin
  1492. SetROP2(windc,R2_XORPEN);
  1493. SetROP2(bitmapdc,R2_XORPEN);
  1494. end;
  1495. AndPut:
  1496. begin
  1497. SetROP2(windc,R2_MASKPEN);
  1498. SetROP2(bitmapdc,R2_MASKPEN);
  1499. end;
  1500. OrPut:
  1501. begin
  1502. SetROP2(windc,R2_MERGEPEN);
  1503. SetROP2(bitmapdc,R2_MERGEPEN);
  1504. end;
  1505. end;
  1506. end;
  1507. }
  1508. col:=RGB(pal[CurrentColor].red,pal[CurrentColor].green,pal[CurrentColor].blue);
  1509. pen:=CreatePen(PS_SOLID,1,col);
  1510. if pen=0 then
  1511. writeln('Pen konnte nicht erzeugt werden!');
  1512. oldpen:=SelectObject(windc,pen);
  1513. MoveToEx(windc,x1,y1,nil);
  1514. Windows.LineTo(windc,x2,y2);
  1515. SetPixel(windc,x2,y2,col);
  1516. SelectObject(windc,oldpen);
  1517. oldpen:=SelectObject(bitmapdc,pen);
  1518. MoveToEx(bitmapdc,x1,y1,nil);
  1519. Windows.LineTo(bitmapdc,x2,y2);
  1520. SetPixel(bitmapdc,x2,y2,col);
  1521. SelectObject(bitmapdc,oldpen);
  1522. DeleteObject(pen);
  1523. {
  1524. if currentwritemode<>normalput then
  1525. begin
  1526. SetROP2(windc,R2_COPYPEN);
  1527. SetROP2(bitmapdc,R2_COPYPEN);
  1528. end;
  1529. }
  1530. LeaveCriticalSection(graphdrawing);
  1531. end
  1532. else
  1533. { Thick width lines }
  1534. begin
  1535. { Draw the pixels }
  1536. for i := 1 to numpixels do
  1537. begin
  1538. { all depending on the slope, we can determine }
  1539. { in what direction the extra width pixels will be put }
  1540. If Flag then
  1541. Begin
  1542. DirectPutPixelClip(x-1,y);
  1543. DirectPutPixelClip(x,y);
  1544. DirectPutPixelClip(x+1,y);
  1545. end
  1546. else
  1547. Begin
  1548. DirectPutPixelClip(x, y-1);
  1549. DirectPutPixelClip(x, y);
  1550. DirectPutPixelClip(x, y+1);
  1551. end;
  1552. if d < 0 then
  1553. begin
  1554. d := d + dinc1;
  1555. x := x + xinc1;
  1556. y := y + yinc1;
  1557. end
  1558. else
  1559. begin
  1560. d := d + dinc2;
  1561. x := x + xinc2;
  1562. y := y + yinc2;
  1563. end;
  1564. end;
  1565. end;
  1566. end;
  1567. end
  1568. else
  1569. {******************************************}
  1570. { begin patterned lines }
  1571. {******************************************}
  1572. Begin
  1573. { Convert to global coordinates. }
  1574. x1 := x1 + StartXViewPort;
  1575. x2 := x2 + StartXViewPort;
  1576. y1 := y1 + StartYViewPort;
  1577. y2 := y2 + StartYViewPort;
  1578. { if fully clipped then exit... }
  1579. if ClipPixels then
  1580. begin
  1581. if LineClipped(x1,y1,x2,y2,StartXViewPort, StartYViewPort,
  1582. StartXViewPort+ViewWidth, StartYViewPort+ViewHeight) then
  1583. exit;
  1584. end;
  1585. OldCurrentColor := CurrentColor;
  1586. PixelCount:=0;
  1587. if y1 = y2 then
  1588. Begin
  1589. { Check if we must swap }
  1590. if x1 >= x2 then
  1591. Begin
  1592. swtmp := x1;
  1593. x1 := x2;
  1594. x2 := swtmp;
  1595. end;
  1596. if LineInfo.Thickness = NormWidth then
  1597. Begin
  1598. for PixelCount:=x1 to x2 do
  1599. { optimization: PixelCount mod 16 }
  1600. if LinePatterns[PixelCount and 15] = TRUE then
  1601. begin
  1602. DirectPutPixel(PixelCount,y2);
  1603. end;
  1604. end
  1605. else
  1606. Begin
  1607. for i:=-1 to 1 do
  1608. Begin
  1609. for PixelCount:=x1 to x2 do
  1610. { Optimization from Thomas - mod 16 = and 15 }
  1611. {this optimization has been performed by the compiler
  1612. for while as well (JM)}
  1613. if LinePatterns[PixelCount and 15] = TRUE then
  1614. begin
  1615. DirectPutPixelClip(PixelCount,y2+i);
  1616. end;
  1617. end;
  1618. end;
  1619. end
  1620. else
  1621. if x1 = x2 then
  1622. Begin
  1623. { Check if we must swap }
  1624. if y1 >= y2 then
  1625. Begin
  1626. swtmp := y1;
  1627. y1 := y2;
  1628. y2 := swtmp;
  1629. end;
  1630. if LineInfo.Thickness = NormWidth then
  1631. Begin
  1632. for PixelCount:=y1 to y2 do
  1633. { compare if we should plot a pixel here , compare }
  1634. { with predefined line patterns... }
  1635. if LinePatterns[PixelCount and 15] = TRUE then
  1636. begin
  1637. DirectPutPixel(x1,PixelCount);
  1638. end;
  1639. end
  1640. else
  1641. Begin
  1642. for i:=-1 to 1 do
  1643. Begin
  1644. for PixelCount:=y1 to y2 do
  1645. { compare if we should plot a pixel here , compare }
  1646. { with predefined line patterns... }
  1647. if LinePatterns[PixelCount and 15] = TRUE then
  1648. begin
  1649. DirectPutPixelClip(x1+i,PixelCount);
  1650. end;
  1651. end;
  1652. end;
  1653. end
  1654. else
  1655. Begin
  1656. oldCurrentColor := CurrentColor;
  1657. { Calculate deltax and deltay for initialisation }
  1658. deltax := abs(x2 - x1);
  1659. deltay := abs(y2 - y1);
  1660. { Initialize all vars based on which is the independent variable }
  1661. if deltax >= deltay then
  1662. begin
  1663. Flag := FALSE;
  1664. { x is independent variable }
  1665. numpixels := deltax + 1;
  1666. d := (2 * deltay) - deltax;
  1667. dinc1 := deltay Shl 1;
  1668. dinc2 := (deltay - deltax) shl 1;
  1669. xinc1 := 1;
  1670. xinc2 := 1;
  1671. yinc1 := 0;
  1672. yinc2 := 1;
  1673. end
  1674. else
  1675. begin
  1676. Flag := TRUE;
  1677. { y is independent variable }
  1678. numpixels := deltay + 1;
  1679. d := (2 * deltax) - deltay;
  1680. dinc1 := deltax Shl 1;
  1681. dinc2 := (deltax - deltay) shl 1;
  1682. xinc1 := 0;
  1683. xinc2 := 1;
  1684. yinc1 := 1;
  1685. yinc2 := 1;
  1686. end;
  1687. { Make sure x and y move in the right directions }
  1688. if x1 > x2 then
  1689. begin
  1690. xinc1 := - xinc1;
  1691. xinc2 := - xinc2;
  1692. end;
  1693. if y1 > y2 then
  1694. begin
  1695. yinc1 := - yinc1;
  1696. yinc2 := - yinc2;
  1697. end;
  1698. { Start drawing at <x1, y1> }
  1699. x := x1;
  1700. y := y1;
  1701. If LineInfo.Thickness=ThickWidth then
  1702. Begin
  1703. TmpNumPixels := NumPixels-1;
  1704. { Draw the pixels }
  1705. for i := 0 to TmpNumPixels do
  1706. begin
  1707. { all depending on the slope, we can determine }
  1708. { in what direction the extra width pixels will be put }
  1709. If Flag then
  1710. Begin
  1711. { compare if we should plot a pixel here , compare }
  1712. { with predefined line patterns... }
  1713. if LinePatterns[i and 15] = TRUE then
  1714. begin
  1715. DirectPutPixelClip(x-1,y);
  1716. DirectPutPixelClip(x,y);
  1717. DirectPutPixelClip(x+1,y);
  1718. end;
  1719. end
  1720. else
  1721. Begin
  1722. { compare if we should plot a pixel here , compare }
  1723. { with predefined line patterns... }
  1724. if LinePatterns[i and 15] = TRUE then
  1725. begin
  1726. DirectPutPixelClip(x,y-1);
  1727. DirectPutPixelClip(x,y);
  1728. DirectPutPixelClip(x,y+1);
  1729. end;
  1730. end;
  1731. if d < 0 then
  1732. begin
  1733. d := d + dinc1;
  1734. x := x + xinc1;
  1735. y := y + yinc1;
  1736. end
  1737. else
  1738. begin
  1739. d := d + dinc2;
  1740. x := x + xinc2;
  1741. y := y + yinc2;
  1742. end;
  1743. end;
  1744. end
  1745. else
  1746. Begin
  1747. { instead of putting in loop , substract by one now }
  1748. TmpNumPixels := NumPixels-1;
  1749. { NormWidth }
  1750. for i := 0 to TmpNumPixels do
  1751. begin
  1752. if LinePatterns[i and 15] = TRUE then
  1753. begin
  1754. DirectPutPixel(x,y);
  1755. end;
  1756. if d < 0 then
  1757. begin
  1758. d := d + dinc1;
  1759. x := x + xinc1;
  1760. y := y + yinc1;
  1761. end
  1762. else
  1763. begin
  1764. d := d + dinc2;
  1765. x := x + xinc2;
  1766. y := y + yinc2;
  1767. end;
  1768. end;
  1769. end
  1770. end;
  1771. {******************************************}
  1772. { end patterned lines }
  1773. {******************************************}
  1774. { restore color }
  1775. CurrentColor:=OldCurrentColor;
  1776. end;
  1777. end;
  1778. end; { Line }
  1779. { multipage support could be done by using more than one background bitmap }
  1780. procedure SetVisualWin32GUI(page: word);
  1781. begin
  1782. end;
  1783. procedure SetActiveWin32GUI(page: word);
  1784. begin
  1785. end;
  1786. function queryadapterinfo : pmodeinfo;
  1787. var
  1788. mode: TModeInfo;
  1789. ScreenWidth,ScreenHeight : longint;
  1790. ScreenWidthMaximized,ScreenHeightMaximized : longint;
  1791. procedure SetupWin32GUIDefault;
  1792. begin
  1793. mode.DirectPutPixel:={$ifdef fpc}@{$endif}DirectPutPixel16Win32GUI;
  1794. mode.PutPixel:={$ifdef fpc}@{$endif}PutPixel16Win32GUI;
  1795. mode.GetPixel:={$ifdef fpc}@{$endif}GetPixel16Win32GUI;
  1796. mode.HLine := {$ifdef fpc}@{$endif}HLine16Win32GUI;
  1797. mode.SetRGBPalette := {$ifdef fpc}@{$endif}SetRGBPaletteWin32GUI;
  1798. mode.GetRGBPalette := {$ifdef fpc}@{$endif}GetRGBPaletteWin32GUI;
  1799. mode.SetVisualPage := {$ifdef fpc}@{$endif}SetVisualWin32GUI;
  1800. mode.SetActivePage := {$ifdef fpc}@{$endif}SetActiveWin32GUI;
  1801. mode.InitMode := {$ifdef fpc}@{$endif}InitWin32GUI16colors;
  1802. mode.OuttextXY:={$ifdef fpc}@{$endif}OuttextXYWin32GUI;
  1803. mode.VLine := {$ifdef fpc}@{$endif}VLine16Win32GUI;
  1804. // mode.circle := {$ifdef fpc}@{$endif}Circle16Win32GUI;
  1805. // doesn't work yet
  1806. // mode.Line:={$ifdef fpc}@{$endif}LineWin32GUI;
  1807. end;
  1808. begin
  1809. SaveVideoState:={$ifdef fpc}@{$endif}savestate;
  1810. RestoreVideoState:={$ifdef fpc}@{$endif}restorestate;
  1811. { we must take care of the border and caption }
  1812. ScreenWidth:=GetSystemMetrics(SM_CXSCREEN)-
  1813. 2*GetSystemMetrics(SM_CXFRAME);
  1814. ScreenHeight:=GetSystemMetrics(SM_CYSCREEN)-
  1815. 2*GetSystemMetrics(SM_CYFRAME)-
  1816. GetSystemMetrics(SM_CYCAPTION);
  1817. { for maximozed windows it's again different }
  1818. { here we've only a caption }
  1819. ScreenWidthMaximized:=GetSystemMetrics(SM_CXFULLSCREEN);
  1820. { neither GetSystemMetrics(SM_CYFULLSCREEN nor }
  1821. { SystemParametersInfo(SPI_GETWORKAREA) }
  1822. { takes a hidden try into account :( FK }
  1823. ScreenHeightMaximized:=GetSystemMetrics(SM_CYFULLSCREEN);
  1824. QueryAdapterInfo := ModeList;
  1825. { If the mode listing already exists... }
  1826. { simply return it, without changing }
  1827. { anything... }
  1828. if assigned(ModeList) then
  1829. exit;
  1830. { the first one becomes the standard mode }
  1831. if (ScreenWidth>=640) and (ScreenHeight>=480) then
  1832. begin
  1833. InitMode(mode);
  1834. mode.DriverNumber:= VGA;
  1835. mode.HardwarePages:= 0;
  1836. mode.ModeNumber:=VGAHi;
  1837. mode.ModeName:='640 x 480 x 16 Win32GUI';
  1838. mode.MaxColor := 16;
  1839. mode.PaletteSize := mode.MaxColor;
  1840. mode.DirectColor := FALSE;
  1841. mode.MaxX := 639;
  1842. mode.MaxY := 479;
  1843. SetupWin32GUIDefault;
  1844. mode.XAspect := 10000;
  1845. mode.YAspect := 10000;
  1846. AddMode(mode);
  1847. end;
  1848. if (ScreenWidth>=640) and (ScreenHeight>=200) then
  1849. begin
  1850. InitMode(mode);
  1851. { now add all standard VGA modes... }
  1852. mode.DriverNumber:= VGA;
  1853. mode.HardwarePages:= 0;
  1854. mode.ModeNumber:=VGALo;
  1855. mode.ModeName:='640 x 200 x 16 Win32GUI';
  1856. mode.MaxColor := 16;
  1857. mode.PaletteSize := mode.MaxColor;
  1858. mode.DirectColor := FALSE;
  1859. mode.MaxX := 639;
  1860. mode.MaxY := 199;
  1861. SetupWin32GUIDefault;
  1862. mode.XAspect := 10000;
  1863. mode.YAspect := 10000;
  1864. AddMode(mode);
  1865. end;
  1866. if (ScreenWidth>=640) and (ScreenHeight>=350) then
  1867. begin
  1868. InitMode(mode);
  1869. mode.DriverNumber:= VGA;
  1870. mode.HardwarePages:= 0;
  1871. mode.ModeNumber:=VGAMed;
  1872. mode.ModeName:='640 x 350 x 16 Win32GUI';
  1873. mode.MaxColor := 16;
  1874. mode.PaletteSize := mode.MaxColor;
  1875. mode.DirectColor := FALSE;
  1876. mode.MaxX := 639;
  1877. mode.MaxY := 349;
  1878. SetupWin32GUIDefault;
  1879. mode.XAspect := 10000;
  1880. mode.YAspect := 10000;
  1881. AddMode(mode);
  1882. end;
  1883. if (ScreenWidth>=640) and (ScreenHeight>=400) then
  1884. begin
  1885. InitMode(mode);
  1886. mode.DriverNumber:= VESA;
  1887. mode.HardwarePages:= 0;
  1888. mode.ModeNumber:=m640x400x256;
  1889. mode.ModeName:='640 x 400 x 256 Win32GUI';
  1890. mode.MaxColor := 256;
  1891. mode.PaletteSize := mode.MaxColor;
  1892. mode.DirectColor := FALSE;
  1893. mode.MaxX := 639;
  1894. mode.MaxY := 399;
  1895. SetupWin32GUIDefault;
  1896. mode.XAspect := 10000;
  1897. mode.YAspect := 10000;
  1898. AddMode(mode);
  1899. end;
  1900. if (ScreenWidth>=640) and (ScreenHeight>=480) then
  1901. begin
  1902. InitMode(mode);
  1903. mode.DriverNumber:= VESA;
  1904. mode.HardwarePages:= 0;
  1905. mode.ModeNumber:=m640x480x256;
  1906. mode.ModeName:='640 x 480 x 256 Win32GUI';
  1907. mode.MaxColor := 256;
  1908. mode.PaletteSize := mode.MaxColor;
  1909. mode.DirectColor := FALSE;
  1910. mode.MaxX := 639;
  1911. mode.MaxY := 479;
  1912. SetupWin32GUIDefault;
  1913. mode.XAspect := 10000;
  1914. mode.YAspect := 10000;
  1915. AddMode(mode);
  1916. end;
  1917. { add 800x600 only if screen is large enough }
  1918. If (ScreenWidth>=800) and (ScreenHeight>=600) then
  1919. begin
  1920. InitMode(mode);
  1921. mode.DriverNumber:= VESA;
  1922. mode.HardwarePages:= 0;
  1923. mode.ModeNumber:=m800x600x16;
  1924. mode.ModeName:='800 x 600 x 16 Win32GUI';
  1925. mode.MaxColor := 16;
  1926. mode.PaletteSize := mode.MaxColor;
  1927. mode.DirectColor := FALSE;
  1928. mode.MaxX := 799;
  1929. mode.MaxY := 599;
  1930. SetupWin32GUIDefault;
  1931. mode.XAspect := 10000;
  1932. mode.YAspect := 10000;
  1933. AddMode(mode);
  1934. InitMode(mode);
  1935. mode.DriverNumber:= VESA;
  1936. mode.HardwarePages:= 0;
  1937. mode.ModeNumber:=m800x600x256;
  1938. mode.ModeName:='800 x 600 x 256 Win32GUI';
  1939. mode.MaxColor := 256;
  1940. mode.PaletteSize := mode.MaxColor;
  1941. mode.DirectColor := FALSE;
  1942. mode.MaxX := 799;
  1943. mode.MaxY := 599;
  1944. SetupWin32GUIDefault;
  1945. mode.XAspect := 10000;
  1946. mode.YAspect := 10000;
  1947. AddMode(mode);
  1948. end;
  1949. { add 1024x768 only if screen is large enough }
  1950. If (ScreenWidth>=1024) and (ScreenHeight>=768) then
  1951. begin
  1952. InitMode(mode);
  1953. mode.DriverNumber:= VESA;
  1954. mode.HardwarePages:= 0;
  1955. mode.ModeNumber:=m1024x768x16;
  1956. mode.ModeName:='1024 x 768 x 16 Win32GUI';
  1957. mode.MaxColor := 16;
  1958. mode.PaletteSize := mode.MaxColor;
  1959. mode.DirectColor := FALSE;
  1960. mode.MaxX := 1023;
  1961. mode.MaxY := 767;
  1962. SetupWin32GUIDefault;
  1963. mode.XAspect := 10000;
  1964. mode.YAspect := 10000;
  1965. AddMode(mode);
  1966. InitMode(mode);
  1967. mode.DriverNumber:= VESA;
  1968. mode.HardwarePages:= 0;
  1969. mode.ModeNumber:=m1024x768x256;
  1970. mode.ModeName:='1024 x 768 x 256 Win32GUI';
  1971. mode.MaxColor := 256;
  1972. mode.PaletteSize := mode.MaxColor;
  1973. mode.DirectColor := FALSE;
  1974. mode.MaxX := 1023;
  1975. mode.MaxY := 768;
  1976. SetupWin32GUIDefault;
  1977. mode.XAspect := 10000;
  1978. mode.YAspect := 10000;
  1979. AddMode(mode);
  1980. end;
  1981. { add 1280x1024 only if screen is large enough }
  1982. If (ScreenWidth>=1280) and (ScreenHeight>=1024) then
  1983. begin
  1984. InitMode(mode);
  1985. mode.DriverNumber:= VESA;
  1986. mode.HardwarePages:= 0;
  1987. mode.ModeNumber:=m1280x1024x16;
  1988. mode.ModeName:='1280 x 1024 x 16 Win32GUI';
  1989. mode.MaxColor := 16;
  1990. mode.PaletteSize := mode.MaxColor;
  1991. mode.DirectColor := FALSE;
  1992. mode.MaxX := 1279;
  1993. mode.MaxY := 1023;
  1994. SetupWin32GUIDefault;
  1995. mode.XAspect := 10000;
  1996. mode.YAspect := 10000;
  1997. AddMode(mode);
  1998. InitMode(mode);
  1999. mode.DriverNumber:= VESA;
  2000. mode.HardwarePages:= 0;
  2001. mode.ModeNumber:=m1280x1024x256;
  2002. mode.ModeName:='1280 x 1024 x 256 Win32GUI';
  2003. mode.MaxColor := 256;
  2004. mode.PaletteSize := mode.MaxColor;
  2005. mode.DirectColor := FALSE;
  2006. mode.MaxX := 1279;
  2007. mode.MaxY := 1023;
  2008. SetupWin32GUIDefault;
  2009. mode.XAspect := 10000;
  2010. mode.YAspect := 10000;
  2011. AddMode(mode);
  2012. end;
  2013. { at least we add a mode with the largest possible window }
  2014. InitMode(mode);
  2015. mode.DriverNumber:= VESA;
  2016. mode.HardwarePages:= 0;
  2017. mode.ModeNumber:=mLargestWindow16;
  2018. mode.ModeName:='Largest Window x 16';
  2019. mode.MaxColor := 16;
  2020. mode.PaletteSize := mode.MaxColor;
  2021. mode.DirectColor := FALSE;
  2022. mode.MaxX := ScreenWidth-1;
  2023. mode.MaxY := ScreenHeight-1;
  2024. SetupWin32GUIDefault;
  2025. mode.XAspect := 10000;
  2026. mode.YAspect := 10000;
  2027. AddMode(mode);
  2028. InitMode(mode);
  2029. mode.DriverNumber:= VESA;
  2030. mode.HardwarePages:= 0;
  2031. mode.ModeNumber:=mLargestWindow256;
  2032. mode.ModeName:='Largest Window x 256';
  2033. mode.MaxColor := 256;
  2034. mode.PaletteSize := mode.MaxColor;
  2035. mode.DirectColor := FALSE;
  2036. mode.MaxX := ScreenWidth-1;
  2037. mode.MaxY := ScreenHeight-1;
  2038. SetupWin32GUIDefault;
  2039. mode.XAspect := 10000;
  2040. mode.YAspect := 10000;
  2041. AddMode(mode);
  2042. { .. and a maximized window }
  2043. InitMode(mode);
  2044. mode.DriverNumber:= VESA;
  2045. mode.HardwarePages:= 0;
  2046. mode.ModeNumber:=mMaximizedWindow16;
  2047. mode.ModeName:='Maximized Window x 16';
  2048. mode.MaxColor := 16;
  2049. mode.PaletteSize := mode.MaxColor;
  2050. mode.DirectColor := FALSE;
  2051. mode.MaxX := ScreenWidthMaximized-1;
  2052. mode.MaxY := ScreenHeightMaximized-1;
  2053. SetupWin32GUIDefault;
  2054. mode.XAspect := 10000;
  2055. mode.YAspect := 10000;
  2056. AddMode(mode);
  2057. InitMode(mode);
  2058. mode.DriverNumber:= VESA;
  2059. mode.HardwarePages:= 0;
  2060. mode.ModeNumber:=mMaximizedWindow256;
  2061. mode.ModeName:='Maximized Window x 256';
  2062. mode.MaxColor := 256;
  2063. mode.PaletteSize := mode.MaxColor;
  2064. mode.DirectColor := FALSE;
  2065. mode.MaxX := ScreenWidthMaximized-1;
  2066. mode.MaxY := ScreenHeightMaximized-1;
  2067. SetupWin32GUIDefault;
  2068. mode.XAspect := 10000;
  2069. mode.YAspect := 10000;
  2070. AddMode(mode);
  2071. end;
  2072. begin
  2073. InitializeGraph;
  2074. charmessagehandler:=nil;
  2075. mousemessagehandler:=nil;
  2076. commandmessagehandler:=nil;
  2077. notifymessagehandler:=nil;
  2078. OnGraphWindowCreation:=nil;
  2079. end.
  2080. {
  2081. $Log$
  2082. Revision 1.15 2005-04-04 16:13:09 peter
  2083. * use smallint
  2084. Revision 1.14 2005/03/31 12:47:20 marco
  2085. * fix from Thomas Schatzl for 3208
  2086. Revision 1.13 2005/02/14 17:13:32 peter
  2087. * truncate log
  2088. }