/// <summary> /// 获取窗口客户区域在屏幕上的位置 /// </summary> /// <param name="hwnd"></param> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="x2"></param> /// <param name="y2"></param> /// <returns></returns> public bool GetClientRect(int hwnd, out int x1, out int y1, out int x2, out int y2) { if (!Win32API.IsWindow((IntPtr)hwnd)) { x1 = -1; y1 = -1; x2 = -1; y2 = -1; return(false); } Win32API.RECT rect = new Win32API.RECT(); bool a = Win32API.GetClientRect((IntPtr)hwnd, out rect); Point point = new Point() { X = rect.Left, Y = rect.Top }; bool b = Win32API.ClientToScreen((IntPtr)hwnd, ref point); x1 = point.X; y1 = point.Y; point = new Point() { X = rect.Right, Y = rect.Bottom }; bool c = Win32API.ClientToScreen((IntPtr)hwnd, ref point); x2 = point.X; y2 = point.Y; return(a && b && c); }
public Canvas(GCsTextEdit view, Font font, bool showLN) { txtZone_ = view.getClientRect(); font_ = new Painter(view.Handle, font); this.showLN = showLN; figNum_ = 3; wrapWidth_ = 0xfffffff; wrapType = WrapType.NonWrap; }
void SetParentBase_GotFocus(object sender, RoutedEventArgs e) { try { if (wp != null) { wp.Activate(); } else if (win.Handle != IntPtr.Zero) { Win32API.RECT rect = new Win32API.RECT(); Win32API.GetWindowRect(win.Handle, ref rect); if (rect.left != 0 || rect.top != 0 || Math.Abs(rect.right - (int)this.ActualWidth) > 5 || Math.Abs(rect.bottom - (int)this.ActualHeight) > 5) { Win32API.SetWindowPos(win.Handle, IntPtr.Zero, 0, 0, (int)this.ActualWidth, (int)this.ActualHeight, (int)0x0040); } } } catch { } }
public void ScrollView(int dx, int dy, bool update) { // スクロール開始通知 cur_.on_scroll_begin(); //Rectangle clip = (dy==0 ? cvs_.zone() : new Rectangle() /*NULL*/); Win32API.RECT clip = (dy == 0 ? cvs_.zone() : new Win32API.RECT()); bool isClipeNull = dy != 0; int H = cvs_.getPainter().H(); // スクロールバー更新 if( dx != 0 ){ // 範囲チェック if( hScrollBar.Value+dx < 0 ) dx = -hScrollBar.Value; else if( hScrollBar.Maximum-hScrollBar.nPage < hScrollBar.Value+dx ) dx = hScrollBar.Maximum-hScrollBar.nPage-hScrollBar.Value+1; //hScrollBar.Value += dx; //::SetScrollInfo( hwnd_, SB_HORZ, &rlScr_, TRUE ); //dx = -dx; hScrollBar.Value += dx; dx = -dx; } if( dy != 0 ){ // 範囲チェック…は前処理で終わってる。 //vScrollBar.Value += dy; //::SetScrollInfo( hwnd_, SB_VERT, &udScr_, TRUE ); //dy *= -H; vScrollBar.Value += dy; dy *= -H; } if( dx!=0 || dy!=0 ){ if( -dx>=right() || dx>=right() || -dy>=bottom() || dy>=bottom() ){ // 全画面再描画 // ちょうど65536の倍数くらいスクロールしたときに、 // ScrollWindowEx on Win9x だと再描画が変なのを回避。 //::InvalidateRect( hwnd_, NULL, FALSE ); this.Invalidate(false); }else{ // 再描画の不要な領域をスクロール //::ScrollWindowEx( hwnd_, dx, dy, NULL, // clip, NULL, NULL, SW_INVALIDATE ); if (isClipeNull) { Win32API.ScrollWindow(this.Handle, dx, dy); } else { Win32API.ScrollWindow(this.Handle, dx, dy, clip); } // 即時再描画? if( update ){ // 縦スクロールは高速化したいので一工夫 if (dy != 0) { if (DrawEventHandler == null) { //// 再描画の必要な領域を自分で計算 //RECT rc = {0,0,right(),bottom()}; //if( dy < 0 ) rc.top = rc.bottom + dy; //else rc.bottom = dy; //// インテリマウスの中ボタンクリックによる //// オートスクロール用カーソルの下の部分を先に描く //// 2回に分けることで、小さな矩形部分二つで済むので高速 //::ValidateRect( hwnd_, &rc ); //::UpdateWindow( hwnd_ ); //::InvalidateRect( hwnd_, &rc, FALSE ); Win32API.RECT rc = new Win32API.RECT(); rc.left = 0; rc.top = 0; rc.right = right(); rc.bottom = bottom(); if (dy < 0) rc.top = rc.bottom + dy; else rc.bottom = dy; Win32API.ValidateRect(this.Handle, ref rc); //this.Update(); Win32API.UpdateWindow(this.Handle); Win32API.InvalidateRect(this.Handle, ref rc, false); } } //else { // Win32API.UpdateWindow(this.Handle); //} //this.Update(); //TODO scroll } } } // スクロール終了通知 cur_.on_scroll_end(); }
//private Point pp = new Point(); private void DrawTXT3(Graphics g, VDrawInfo v, Painter p) { //doc_.line(0).Block.pa //g.FillRectangle(bb, v.rc); // 定数1 // const int TAB = p.T(); int H = p.H(); int TLM = doc_.tln() - 1; int tmpYMIN = 0; int tmpTLMIN = 0; //if (DrawEventHandler == null) { // tmpYMIN = v.YMIN; // tmpTLMIN = v.TLMIN; //} //else { // var tuple = l(udScr_tl_, udScr_vrl_); // tmpYMIN = -(tuple.t2 + udScr_vrl_) * H; // tmpTLMIN = tuple.t1; //} //if (DrawEventHandler != null && v.YMIN<=0) { if (DrawEventHandler != null ) { var tuple = l(udScr_tl_, udScr_vrl_); tmpYMIN = -(tuple.t2 + udScr_vrl_) * H; tmpTLMIN = tuple.t1; } else { tmpYMIN = v.YMIN; tmpTLMIN = v.TLMIN; } //var tuple = l(udScr_tl_, udScr_vrl_); //int tmpYMIN = -(tuple.t2 + udScr_vrl_) * H; //int tmpTLMIN = tuple.t1; //int testYMIN = -(tuple.t2 + udScr_vrl_) * H; //int testTLMIN = tuple.t1; // 作業用変数1 //Win32API.RECT a = new Win32API.RECT { left = 0, top = v.YMIN, right = 0, bottom = v.YMIN + p.H() }; Win32API.RECT a = new Win32API.RECT { left = 0, top = tmpYMIN, right = 0, bottom = tmpYMIN + p.H() }; //Rectangle a = new Rectangle( 0, v.YMIN, 0, v.YMIN+p.H() ); //Rectangle a = new Rectangle(0, 0,,v.YMIN); //int clr = -1; int x=0; int xbk = 0; int i=0; Color color = Color.Empty; Token token = null; Action<IText> draw = (itext) => { string s = itext.ToString(); int ci = s.IndexOfAny(cs, 0); if (ci < 0) { //p.DrawText(g, s, color, x + v.XBASE, a.top); p.DrawText(g, s, token.attr, x + v.XBASE, a.top); if (((token.attr.type & AttrType.Image) == AttrType.Image) && i == token.ad && DrawEventHandler != null) { //DrawEventHandler(g, s.Substring(token.ad, token.len), x + v.XBASE, a.top + H); DrawEventHandler(g, s, x + v.XBASE, a.top + H); } x += p.CalcStringWidth(s); i += itext.Length; } else { foreach (var ps in Painter.parse(s, cs)) { switch (ps[0]) { case ' ': if (ShowWhiteSpace) p.DrawHSP(g, x + v.XBASE, a.top, ps.Length); x += p.CalcStringWidth(ps); break; case '\x3000': //' ': if (ShowZenWhiteSpace) p.DrawZen(g, x + v.XBASE, a.top, ps.Length); x += p.CalcStringWidth(ps); break; case '\t': if (ShowTab) { for (int i2 = 0; i2 < ps.Length; ++i2) { int ntx = p.nextTab(x); p.DrawTab(g, x + v.XBASE, a.top, ntx - x); x = ntx; } } break; default: //p.DrawText(g, ps, color, x + v.XBASE, a.top); p.DrawText(g, ps, token.attr, x + v.XBASE, a.top); if (((token.attr.type & AttrType.Image) == AttrType.Image) && i == token.ad && DrawEventHandler != null) { DrawEventHandler(g, ps.Substring(token.ad, token.len), x + v.XBASE, a.top + H); } x += p.CalcStringWidth(ps); break; } i += ps.Length; } } p.DrawAttribute(g, token.attr, v.XBASE + xbk, a.top - 1, v.XBASE + x, a.top - 1); }; //int aTop = a.Top; //int aBottom = a.Bottom; // 論理行単位のLoop //for (int tl = tmpTLMIN; a.top < v.YMAX && tl < doc_.tln(); ++tl) { for (int tl = tmpTLMIN; a.top < v.YMAX; ++tl) { //for (int tl = tmpTLMIN; a.top < v.YMAX; ++tl) { //TODO test //string pa = doc_.line(tl).Block.PartID; // 定数2 //string str = doc_.tl(tl).ToString(); IText str = doc_.tl(tl); //if (str.Length == 0) break; //const uchar* flg = doc_.pl(tl); int rYMAX = Math.Min(v.YMAX, a.top + rln(tl) * H); // 作業用変数2 int stt = 0, end; int index = 0; int nextlen = 0; var rules = doc_.Rules(tl); if (rules.Count == 0) return; token = rules[index]; int tokenad = token.ad; int tokenlen = token.len; color = token.attr.color; // 表示行単位のLoop for (int rl = 0; a.top < rYMAX; ++rl, a.top += H, a.bottom += H, stt = end) { // 作業用変数3 end = rlend(tl, rl); if (a.bottom <= tmpYMIN) continue; ////TODO test //if (pa != Document.DEFAULT_ID) { // p.DrawFill(g, 0, a.top, v.XMAX + v.XBASE, H); //} // テキストデータ描画 for (x = 0, i=stt; x <= v.XMAX && i < end; ) { xbk = x; nextlen = end - (tokenad + tokenlen); //nextlen = end - attrindex; if (nextlen >= 0) { var text = str.Substring(tokenad, tokenlen); //draw(str, tokenad, tokenlen); draw(text); stt = i; if (nextlen > 0) { index++; token = rules[index]; tokenad = token.ad; tokenlen = token.len; color = token.attr.color; } if (rln(tl) > 0 && nextlen == 0 && i == end && index < rules.Count-1) { index++; token = rules[index]; tokenad = token.ad; tokenlen = token.len; color = token.attr.color; } } else { //over var text = str.Substring(tokenad, end - tokenad); draw(text); //draw(str, tokenad, end - tokenad); stt = i; tokenlen -= text.Length; //(end - attrindex); tokenad = end; } } // 選択範囲だったら反転 //if( v.SYB<=a.top && a.top<=v.SYE ) // Inv( a.top, a.top==v.SYB?v.SXB:(v.XBASE), // a.top==v.SYE?v.SXE:(v.XBASE+x), p ); if (v.SYB <= a.top && a.top <= v.SYE) { //TODO Rectangle if (cur_.Selection == SelectionType.Rectangle) { int cx = cur_.caret.GetPos().X; if (cur_.Cur.tl == tl && cur_.Cur.rl == rl) { for (int selY = v.SYB; selY <= v.SYE; selY += H) { //VPos vpb = new VPos(); //GetVPos(v.SXB, selY, ref vpb, false); VPos vpe = new VPos(); GetVPos(cx, selY, ref vpe, false); //int w = CalcLineWidth(doc_.tl(vpe.tl).ToString(), doc_.tl(vpe.tl).Length); if (CalcLineWidth(doc_.tl(vpe.tl).ToString(), doc_.tl(vpe.tl).Length) + v.XBASE < cx) { Inv(g, selY, Math.Min(v.XBASE + cur_.Sel.vx, cx), Math.Max(v.XBASE + cur_.Sel.vx, cx), p); } else { Inv(g, selY, Math.Min(v.XBASE + cur_.Sel.vx, v.XBASE + vpe.vx), Math.Max(v.XBASE + cur_.Sel.vx, v.XBASE + vpe.vx), p); } //Inv(g, selY, Math.Min(v.XBASE + cur_.Sel.vx, cx), // Math.Max(v.XBASE + cur_.Sel.vx, cx), p); } } } else { Inv(g, a.top, a.top == v.SYB ? v.SXB : (v.XBASE), a.top == v.SYE ? v.SXE : (v.XBASE + x), p); } } // 行末より後ろの余白を背景色塗 if (x < v.XMAX) { a.left = v.XBASE + Math.Max(v.XMIN, x); a.right = v.XBASE + v.XMAX; //p.Fill( a ); //g.FillRectangle(bb, a.left, a.top, a.right - a.left, a.bottom - a.top); } } //// 行末記号描画反転 //SpecialChars sc = (tl==TLM ? scEOF : scEOL); //if( i==doc_.len(tl) && -32768<x+v.XBASE ) //{ // if( p.sc(sc) ) // { // static const unicode* const sstr[] = { L"[EOF]", L"/" }; // static const int slen[] = { 5, 1 }; // p.SetColor( clr=CTL ); // p.StringOut( sstr[sc], slen[sc], x+v.XBASE, a.top-H ); // } // if( v.SYB<a.top && a.top<=v.SYE && sc==scEOL ) // Inv( a.top-H, x+v.XBASE, x+v.XBASE+p.Wc('/'), p ); //} if( i==doc_.len(tl) && -32768<x+v.XBASE ){ if (ShowReturn && tl != TLM) { p.DrawReturn(g, x + v.XBASE, a.top - H); } if (cur_.Selection == SelectionType.Normal && v.SYB < a.top && a.top <= v.SYE && ShowReturn) Inv(g, a.top - H, x + v.XBASE, x + v.XBASE + p.W(), p); } } // EOF後余白を背景色塗 if (a.top < v.rc.Bottom) { a.left = v.rc.Left; a.right = v.rc.Right; a.bottom = v.rc.Bottom; //p.Fill( a ); //g.FillRectangle(bb, a.left, a.top, a.right - a.left, a.bottom - a.top); } //v.YMIN = tmpYMIN; //v.TLMIN = tmpTLMIN; }