⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reportcontrol.pas

📁 delphi编程控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  If (ThisCell <> Nil) And (ThisCell.CellWidth > 10) Then
    Begin
      FEditCell := ThisCell;

      If FEditFont <> INVALID_HANDLE_VALUE Then
        DeleteObject(FEditFont);

      FEditFont := CreateFontIndirect(ThisCell.LogFont);

      // 设置编辑窗的字体
      If IsWindow(FEditWnd) Then
        Begin
          DestroyWindow(FEditWnd);
        End;

      //// Edit Window's Position
      Case ThisCell.HorzAlign Of
        TEXT_ALIGN_LEFT :
          dwStyle := WS_VISIBLE Or WS_CHILD Or ES_MULTILINE Or ES_LEFT Or ES_AUTOVSCROLL;
        TEXT_ALIGN_CENTER :
          dwStyle := WS_VISIBLE Or WS_CHILD Or ES_MULTILINE Or ES_CENTER Or ES_AUTOVSCROLL;
        TEXT_ALIGN_RIGHT :
          dwStyle := WS_VISIBLE Or WS_CHILD Or ES_MULTILINE Or ES_RIGHT Or ES_AUTOVSCROLL;
      Else
        dwStyle := WS_VISIBLE Or WS_CHILD Or ES_MULTILINE Or ES_LEFT Or ES_AUTOVSCROLL;
      End;

      FEditWnd := CreateWindow('EDIT', '', dwStyle, 0, 0, 0, 0, Handle, 1, hInstance, Nil);

      SendMessage(FEditWnd, WM_SETFONT, FEditFont, 1); // 1 means TRUE here.
      SendMessage(FEditWnd, EM_LIMITTEXT, 1000, 0);

      MoveWindow(FEditWnd, ThisCell.TextRect.left, ThisCell.TextRect.Top,
        ThisCell.TextRect.Right - ThisCell.TextRect.Left,
        ThisCell.TextRect.Bottom - ThisCell.TextRect.Top, True);
      SetWindowText(FEditWnd, PChar(ThisCell.CellText));
      ShowWindow(FEditWnd, SW_SHOWNORMAL);
      Windows.SetFocus(FEditWnd);
    End;
End;

Procedure TReportControl.WMLButtonDown(Var Message : TMessage);
Var
  ThisCell : TReportCell;
  MousePoint : TPoint;
  TempChar : Array[0..1000] Of Char;
  TempMsg : TMSG;
  TempRect : TRect;
Begin
  MousePoint.x := LOWORD(Message.lParam);
  MousePoint.y := HIWORD(Message.lParam);
  ThisCell := CellFromPoint(MousePoint);

  If IsWindowVisible(FEditWnd) Then
    Begin
      If FEditCell <> Nil Then
        Begin
          GetWindowText(FEditWnd, TempChar, 1000);
          FEditCell.CellText := TempChar;
        End;
      // 奇怪,ReportControl窗口一旦得到焦点就移动自己
      Windows.SetFocus(0);
      DestroyWindow(FEditWnd);
      FEditCell := Nil;
    End;

  // 清除消息队列中的WM_PAINT消息,防止画出飞线
  While PeekMessage(TempMsg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE) Do
    Begin
      If Not GetMessage(TempMsg, 0, WM_PAINT, WM_PAINT) Then
        Break;

      DispatchMessage(TempMsg);
    End;

  If ThisCell = Nil Then
    StartMouseSelect(MousePoint, True)
  Else
    Begin
      TempRect := ThisCell.CellRect;

      If (abs(TempRect.Bottom - MousePoint.y) <= 3) Or
        (abs(TempRect.Right - MousePoint.x) <= 3) Then
        StartMouseDrag(MousePoint)
      Else
        StartMouseSelect(MousePoint, True);
      {
          else if abs(TempRect.left - MousePoint.x) <= 5 then
            StartMouseSelect(MousePoint, True)
          else
            StartMouseSelect(MousePoint, False);
      }
    End;
End;

Procedure TReportControl.WMMouseMove(Var Message : TMessage);
Var
  ThisCell : TReportCell;
  MousePoint : TPoint;
  RectCell : TRect;
Begin
  MousePoint.x := LOWORD(Message.lParam);
  MousePoint.y := HIWORD(Message.lParam);
  ThisCell := CellFromPoint(MousePoint);

  If ThisCell <> Nil Then
    Begin
      RectCell := ThisCell.CellRect;

      If abs(RectCell.Right - MousePoint.x) <= 3 Then
        SetCursor(LoadCursor(0, IDC_SIZEWE))
      Else If abs(RectCell.Bottom - MousePoint.y) <= 3 Then
        SetCursor(LoadCursor(0, IDC_SIZENS))
      Else If abs(RectCell.left - MousePoint.x) <= 5 Then
        SetCursor(LoadCursor(0, IDC_UPARROW))
      Else
        SetCursor(LoadCursor(0, IDC_IBEAM));
    End
  Else
    SetCursor(LoadCursor(0, IDC_ARROW));
  Inherited;
End;

Procedure TReportControl.WMContextMenu(Var Message : TMessage);
Var
  ThisCell : TReportCell;
  TempPoint : TPoint;
Begin
  GetCursorPos(TempPoint);
  Windows.ScreenToClient(Handle, TempPoint);
  ThisCell := CellFromPoint(TempPoint);

  If Not IsCellSelected(ThisCell) Then
    Begin
      RemoveAllSelectedCell;
      If ThisCell <> Nil Then
        Begin
          AddSelectedCell(ThisCell);
        End;
    End;
End;

Procedure TReportControl.StartMouseDrag(point : TPoint);
Var
  TempCell, TempNextCell, ThisCell, NextCell : TReportCell;
  ThisCellsList : TList;
  TempRect, RectBorder, RectCell, RectClient : TRect;
  hClientDC : HDC;
  hInvertPen, hPrevPen : HPEN;
  PrevDrawMode, PrevCellWidth, Distance : Integer;
  I, J : Integer;
  bHorz, bSelectFlag : Boolean;
  ThisLine, TempLine : TReportLine;
  TempMsg : TMSG;
  BottomCell : TReportCell;
  Top : Integer;
  //  CellList : TList;
  DragBottom : Integer;
Begin
  ThisCell := CellFromPoint(point);
  RectCell := ThisCell.CellRect;
  FMousePoint := point;
  Windows.GetClientRect(Handle, RectClient);
  ThisCellsList := TList.Create;

  // 设置线形和绘制模式
  hClientDC := GetDC(Handle);
  hInvertPen := CreatePen(PS_DOT, 1, RGB(0, 0, 0));
  hPrevPen := SelectObject(hClientDC, hInvertPen);

  PrevDrawMode := SetROP2(hClientDC, R2_NOTXORPEN);

  // 置横向标志
  If abs(RectCell.Bottom - point.y) <= 3 Then
    bHorz := True
  Else
    bHorz := False;
  // 计算上下左右边界
  ThisLine := ThisCell.OwnerLine;
  RectBorder.Top := ThisLine.LineTop + 5;
  RectBorder.Bottom := Height - 10;
  RectBorder.Right := ClientRect.Right;

  NextCell := Nil;

  For I := 0 To ThisLine.FCells.Count - 1 Do
    Begin
      TempCell := TReportCell(ThisLine.FCells[I]);

      If ThisCell = TempCell Then
        Begin
          RectBorder.Left := ThisCell.CellLeft + 10;

          If I < ThisLine.FCells.Count - 1 Then
            Begin
              NextCell := TReportCell(ThisLine.FCells[I + 1]);
              RectBorder.Right := NextCell.CellLeft + NextCell.CellWidth - 10;
            End
          Else
            RectBorder.Right := ClientRect.Right - 10;
        End;
    End;

  If Not bHorz Then
    Begin
      // 若无选中的CELL,或者要改变宽度的CELL和NEXTCELL不在选中区中
      bSelectFlag := False;

      If FSelectCells.Count <= 0 Then
        bSelectFlag := True;

      If NextCell = Nil Then
        Begin
          If (Not IsCellSelected(ThisCell)) And (Not IsCellSelected(NextCell)) Then
            bSelectFlag := True;
        End
      Else
        If (Not IsCellSelected(ThisCell)) And (Not IsCellSelected(NextCell)) And
        (Not IsCellSelected(NextCell.OwnerCell)) Then
        bSelectFlag := True;

      If bSelectFlag Then
        Begin
          For I := 0 To FLineList.Count - 1 Do
            Begin
              TempLine := TReportLine(FLineList[I]);
              For J := 0 To TempLine.FCells.Count - 1 Do
                Begin
                  TempCell := TReportCell(TempLine.FCells[J]);
                  // 若该CELL的右边等于选中的CELL的右边,将该CELL和NEXTCELL加入到两个LIST中去
                  If TempCell.CellRect.Right = ThisCell.CellRect.Right Then
                    Begin
                      ThisCellsList.Add(TempCell);

                      If TempCell.CellLeft + 10 > RectBorder.Left Then
                        RectBorder.Left := TempCell.CellLeft + 10;

                      If J < TempLine.FCells.Count - 1 Then
                        Begin
                          TempNextCell := TReportCell(TempLine.FCells[J + 1]);
                          If TempNextCell.CellRect.Right - 10 < RectBorder.Right Then
                            RectBorder.Right := TempNextCell.CellRect.Right - 10;
                        End;
                    End;
                End;
            End;
        End
      Else
        Begin
          For I := 0 To FLineList.Count - 1 Do
            Begin
              TempLine := TReportLine(FLineList[I]);
              TempNextCell := Nil;
              For J := 0 To TempLine.FCells.Count - 1 Do
                Begin
                  TempCell := TReportCell(TempLine.FCells[J]);
                  // 若该CELL的右边等于选中的CELL的右边,将该CEL加入到LIST中去
                  // 前提是CELL或NEXTCELL在选中区内
                  If (TempCell.CellRect.Right = ThisCell.CellRect.Right) Then
                    Begin
                      If J < TempLine.FCells.Count - 1 Then
                        TempNextCell := TReportCell(TempLine.FCells[J + 1]);

                      If (Not IsCellSelected(TempNextCell)) And (Not IsCellSelected(TempCell)) Then
                        Break;

                      If TempNextCell <> Nil Then
                        Begin
                          If TempNextCell.CellRect.Right - 10 < RectBorder.Right Then
                            RectBorder.Right := TempNextCell.CellRect.Right - 10;
                        End;

                      ThisCellsList.Add(TempCell);

                      If TempCell.CellLeft + 10 > RectBorder.Left Then
                        RectBorder.Left := TempCell.CellLeft + 10;

                      Break;
                    End;
                End;
            End;
        End;
    End;

  // 画第一条线
  If bHorz Then
    Begin
      FMousePoint.y := trunc(FMousePoint.y / 5 * 5 + 0.5);

      If FMousePoint.y < RectBorder.Top Then
        FMousePoint.y := RectBorder.Top;

      If FMousePoint.y > RectBorder.Bottom Then
        FMousePoint.y := RectBorder.Bottom;

      MoveToEx(hClientDC, 0, FMousePoint.y, Nil);
      LineTo(hClientDC, RectClient.Right, FMousePoint.y);
      SetCursor(LoadCursor(0, IDC_SIZENS));
    End
  Else
    Begin
      FMousePoint.x := trunc(FMousePoint.x / 5 * 5 + 0.5);

      If FMousePoint.x < RectBorder.Left Then
        FMousePoint.x := RectBorder.Left;

      If FMousePoint.x > RectBorder.Right Then
        FMousePoint.x := RectBorder.Right;

      MoveToEx(hClientDC, FMousePoint.x, 0, Nil);
      LineTo(hClientDC, FMousePoint.x, RectClient.Bottom);
      SetCursor(LoadCursor(0, IDC_SIZEWE));
    End;

  SetCapture(Handle);

  // 取得鼠标输入,进入第二个消息循环
  While GetCapture = Handle Do
    Begin
      If Not GetMessage(TempMsg, Handle, 0, 0) Then
        Begin
          PostQuitMessage(TempMsg.wParam);
          Break;
        End;

      Case TempMsg.message Of
        WM_LBUTTONUP :
          ReleaseCapture;
        WM_MOUSEMOVE :
          If bHorz Then
            Begin
              MoveToEx(hClientDC, 0, FMousePoint.y, Nil);
              LineTo(hClientDC, RectClient.Right, FMousePoint.y);
              FMousePoint := TempMsg.pt;
              Windows.ScreenToClient(Handle, FMousePoint);

              // 边界检查
              FMousePoint.y := trunc(FMousePoint.y / 5 * 5 + 0.5);

              If FMousePoint.y < RectBorder.Top Then
                FMousePoint.y := RectBorder.Top;

              If FMousePoint.y > RectBorder.Bottom Then
                FMousePoint.y := RectBorder.Bottom;

              MoveToEx(hClientDC, 0, FMousePoint.y, Nil);
              LineTo(hClientDC, RectClient.Right, FMousePoint.y);
            End
          Else
            Begin
              MoveToEx(hClientDC, FMousePoint.x, 0, Nil);
              LineTo(hClientDC, FMousePoint.x, RectClient.Bottom);
              FMousePoint := TempMsg.pt;
              Windows.ScreenToClient(Handle, FMousePoint);

              // 边界检查
              FMousePoint.x := trunc(FMousePoint.x / 5 * 5 + 0.5);

              If FMousePoint.x < RectBorder.Left Then
                FMousePoint.x := RectBorder.Left;
              If FMousePoint.x > RectBorder.Right Then
                FMousePoint.x := RectBorder.Right;

              MoveToEx(hClientDC, FMousePoint.x, 0, Nil);
              LineTo(hClientDC, FMousePoint.x, RectClient.Bottom);
            End;
        WM_SETCURSOR :
          ;
      Else
        DispatchMessage(TempMsg);
      End;
    End;

  If GetCapture = Handle Then
    ReleaseCapture;

  If bHorz Then
    Begin
      // 将反显的线去掉
      MoveToEx(hClientDC, 0, FMousePoint.y, Nil);
      LineTo(hClientDC, RectClient.Right, FMousePoint.y);

      // 改变行高
      // 改变行高
      If ThisCell.FCellsList.Count <= 0 Then
        Begin
          // 不跨越其他CELL时
          BottomCell := ThisCell;
        End
      Else
        Begin
          // 跨越其他CELL时,取得最下一行的CELL
          BottomCell := Nil;
          Top := 0;
          For I := 0 To ThisCell.FCellsList.Count - 1 Do
            Begin
              If TReportCell(ThisCell.FCellsList[I]).CellTop > Top Then
                Begin
                  BottomCell := TReportCell(ThisCell.FCellsList[I]);
                  Top := BottomCell.CellTop;
                End;
            End;
        End;

      BottomCell.CalcMinCellHeight;
      BottomCell.OwnerLine.LineHeight := FMousePoint.Y - BottomCell.OwnerLine.LineTop;
      UpdateLines;
    End
  Else
    Begin
      // 将反显的线去掉
      MoveToEx(hClientDC, FMousePoint.x, 0, Nil);
      LineTo(hClientDc, FMousePoint.x, RectClient.Bottom);

      // 在此处判断对CELL宽度的设定是否有效
      DragBottom := ThisCellsList.Count;

      For I := 0 To DragBottom - 1 Do
        Begin
          For J := 0 To TReportCell(ThisCellsList[I]).FCellsList.Count - 1 Do
            Begin
              ThisCellsList.Add(TReportCell(ThisCellsList[I]).FCellsList[J]);
            End;
        End;

      // 取得NEXTCELL
      If ThisCellsList.Count > 0 Then
        Begin
          ThisCell := TReportCell(ThisCellsList[0]);
          If ThisCell.CellIndex < ThisCell.OwnerLine.FCells.Count - 1 Then
            NextCell := TReportCell(ThisCell.OwnerLine.FCells[ThisCell.CellIndex + 1]);

          // 右边的CELL不为空且隶属与某一CELL
          If NextCell <> Nil Then
            Begin
              If NextCell.OwnerCell <> Nil Then
                Begin
                  SelectObject(hClientDC, hPrevPen);
                  DeleteObject(hInvertPen);
                  SetROP2(hClientDc, PrevDrawMode);
                  ReleaseDC(Handle, hClientDC);
                  Exit;
                End;
            End;

          DragBottom := 0;
          For I := 0 To ThisCellsList.Count - 1 Do
            Begin
              If TReportCell(ThisCellsList[I]).CellRect.Bottom > DragBottom Then
                DragBottom := TReportCell(ThisCellsList[I]).CellRect.Bottom;
            End;

          For I := 0 To ThisCellsList.Count - 1 Do
   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -